diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
24 files changed, 1273 insertions, 895 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5063e01410e5..d49e830fa1da 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 | ||
323 | static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, | 323 | static 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, ®); | 335 | |
335 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); | 336 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
336 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); | 337 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); |
337 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); | 338 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); |
338 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); | 339 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); |
339 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 340 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); |
340 | 341 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | |
341 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 342 | |
342 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 343 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
343 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 344 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
344 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); | 345 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
345 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 346 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
346 | 347 | GET_DURATION(ACK_SIZE, 10)); | |
347 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | 348 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); |
348 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 349 | |
349 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 350 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); |
350 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); | 351 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
351 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | 352 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
352 | 353 | rt2x00_set_field32(®, ARCSR2_LENGTH, | |
353 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | 354 | GET_DURATION(ACK_SIZE, 20)); |
354 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 355 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); |
355 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 356 | |
356 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); | 357 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); |
357 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | 358 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
358 | 359 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | |
359 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | 360 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
360 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 361 | GET_DURATION(ACK_SIZE, 55)); |
361 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 362 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); |
362 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); | 363 | |
363 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 364 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); |
364 | 365 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | |
365 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); | 366 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
367 | rt2x00_set_field32(®, ARCSR2_LENGTH, | ||
368 | GET_DURATION(ACK_SIZE, 110)); | ||
369 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | ||
370 | } | ||
366 | 371 | ||
367 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 372 | if (changed & BSS_CHANGED_BASIC_RATES) |
368 | rt2x00_set_field32(®, 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, ®); | 375 | if (changed & BSS_CHANGED_ERP_SLOT) { |
372 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); | 376 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); |
373 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); | 377 | rt2x00_set_field32(®, 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, ®); | 380 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); |
377 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); | 381 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); |
378 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); | 382 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); |
379 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); | 383 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); |
384 | |||
385 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | ||
386 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); | ||
387 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); | ||
388 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | ||
389 | } | ||
380 | 390 | ||
381 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | 391 | if (changed & BSS_CHANGED_BEACON_INT) { |
382 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); | 392 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); |
383 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); | 393 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, |
384 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | 394 | erp->beacon_int * 16); |
395 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, | ||
396 | erp->beacon_int * 16); | ||
397 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | ||
398 | } | ||
385 | } | 399 | } |
386 | 400 | ||
387 | static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev, | 401 | static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev, |
@@ -1007,12 +1021,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1007 | /* | 1021 | /* |
1008 | * TX descriptor initialization | 1022 | * TX descriptor initialization |
1009 | */ | 1023 | */ |
1010 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1024 | static void rt2400pci_write_tx_desc(struct queue_entry *entry, |
1011 | struct sk_buff *skb, | ||
1012 | struct txentry_desc *txdesc) | 1025 | struct txentry_desc *txdesc) |
1013 | { | 1026 | { |
1014 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1027 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1015 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1028 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1016 | __le32 *txd = entry_priv->desc; | 1029 | __le32 *txd = entry_priv->desc; |
1017 | u32 word; | 1030 | u32 word; |
1018 | 1031 | ||
@@ -1096,7 +1109,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1096 | /* | 1109 | /* |
1097 | * Write the TX descriptor for the beacon. | 1110 | * Write the TX descriptor for the beacon. |
1098 | */ | 1111 | */ |
1099 | rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1112 | rt2400pci_write_tx_desc(entry, txdesc); |
1100 | 1113 | ||
1101 | /* | 1114 | /* |
1102 | * Dump beacon to userspace through debugfs. | 1115 | * Dump beacon to userspace through debugfs. |
@@ -1112,24 +1125,24 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1112 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1125 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1113 | } | 1126 | } |
1114 | 1127 | ||
1115 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1128 | static void rt2400pci_kick_tx_queue(struct data_queue *queue) |
1116 | const enum data_queue_qid queue) | ||
1117 | { | 1129 | { |
1130 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1118 | u32 reg; | 1131 | u32 reg; |
1119 | 1132 | ||
1120 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1133 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
1121 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); | 1134 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); |
1122 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); | 1135 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); |
1123 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); | 1136 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); |
1124 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1137 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1125 | } | 1138 | } |
1126 | 1139 | ||
1127 | static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 1140 | static void rt2400pci_kill_tx_queue(struct data_queue *queue) |
1128 | const enum data_queue_qid qid) | ||
1129 | { | 1141 | { |
1142 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1130 | u32 reg; | 1143 | u32 reg; |
1131 | 1144 | ||
1132 | if (qid == QID_BEACON) { | 1145 | if (queue->qid == QID_BEACON) { |
1133 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 1146 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); |
1134 | } else { | 1147 | } else { |
1135 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1148 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
@@ -1481,15 +1494,17 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1481 | /* | 1494 | /* |
1482 | * Create channel information array | 1495 | * Create channel information array |
1483 | */ | 1496 | */ |
1484 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 1497 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
1485 | if (!info) | 1498 | if (!info) |
1486 | return -ENOMEM; | 1499 | return -ENOMEM; |
1487 | 1500 | ||
1488 | spec->channels_info = info; | 1501 | spec->channels_info = info; |
1489 | 1502 | ||
1490 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | 1503 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); |
1491 | for (i = 0; i < 14; i++) | 1504 | for (i = 0; i < 14; i++) { |
1492 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 1505 | info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER); |
1506 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
1507 | } | ||
1493 | 1508 | ||
1494 | return 0; | 1509 | return 0; |
1495 | } | 1510 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c2a555d5376b..2214c3231727 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -327,7 +327,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
327 | } | 327 | } |
328 | 328 | ||
329 | static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, | 329 | static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, |
330 | struct rt2x00lib_erp *erp) | 330 | struct rt2x00lib_erp *erp, |
331 | u32 changed) | ||
331 | { | 332 | { |
332 | int preamble_mask; | 333 | int preamble_mask; |
333 | u32 reg; | 334 | u32 reg; |
@@ -335,59 +336,73 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
335 | /* | 336 | /* |
336 | * When short preamble is enabled, we should set bit 0x08 | 337 | * When short preamble is enabled, we should set bit 0x08 |
337 | */ | 338 | */ |
338 | preamble_mask = erp->short_preamble << 3; | 339 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
339 | 340 | preamble_mask = erp->short_preamble << 3; | |
340 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 341 | |
341 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); | 342 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
342 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); | 343 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); |
343 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); | 344 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); |
344 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); | 345 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); |
345 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 346 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); |
346 | 347 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | |
347 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 348 | |
348 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 349 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
349 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 350 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
350 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); | 351 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
351 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 352 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
352 | 353 | GET_DURATION(ACK_SIZE, 10)); | |
353 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | 354 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); |
354 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 355 | |
355 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 356 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); |
356 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); | 357 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
357 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | 358 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
358 | 359 | rt2x00_set_field32(®, ARCSR2_LENGTH, | |
359 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | 360 | GET_DURATION(ACK_SIZE, 20)); |
360 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 361 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); |
361 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 362 | |
362 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); | 363 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); |
363 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | 364 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
364 | 365 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | |
365 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | 366 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
366 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 367 | GET_DURATION(ACK_SIZE, 55)); |
367 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 368 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); |
368 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); | 369 | |
369 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 370 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); |
370 | 371 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | |
371 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); | 372 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
373 | rt2x00_set_field32(®, ARCSR2_LENGTH, | ||
374 | GET_DURATION(ACK_SIZE, 110)); | ||
375 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | ||
376 | } | ||
372 | 377 | ||
373 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 378 | if (changed & BSS_CHANGED_BASIC_RATES) |
374 | rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); | 379 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); |
375 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
376 | 380 | ||
377 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); | 381 | if (changed & BSS_CHANGED_ERP_SLOT) { |
378 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); | 382 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); |
379 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); | 383 | rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); |
380 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | 384 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
381 | 385 | ||
382 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); | 386 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); |
383 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); | 387 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); |
384 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); | 388 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); |
385 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); | 389 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); |
390 | |||
391 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | ||
392 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); | ||
393 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); | ||
394 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | ||
395 | } | ||
396 | |||
397 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
398 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); | ||
399 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, | ||
400 | erp->beacon_int * 16); | ||
401 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, | ||
402 | erp->beacon_int * 16); | ||
403 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | ||
404 | } | ||
386 | 405 | ||
387 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | ||
388 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); | ||
389 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); | ||
390 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | ||
391 | } | 406 | } |
392 | 407 | ||
393 | static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, | 408 | static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, |
@@ -1161,12 +1176,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1161 | /* | 1176 | /* |
1162 | * TX descriptor initialization | 1177 | * TX descriptor initialization |
1163 | */ | 1178 | */ |
1164 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1179 | static void rt2500pci_write_tx_desc(struct queue_entry *entry, |
1165 | struct sk_buff *skb, | ||
1166 | struct txentry_desc *txdesc) | 1180 | struct txentry_desc *txdesc) |
1167 | { | 1181 | { |
1168 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1182 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1169 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1183 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1170 | __le32 *txd = entry_priv->desc; | 1184 | __le32 *txd = entry_priv->desc; |
1171 | u32 word; | 1185 | u32 word; |
1172 | 1186 | ||
@@ -1249,7 +1263,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1249 | /* | 1263 | /* |
1250 | * Write the TX descriptor for the beacon. | 1264 | * Write the TX descriptor for the beacon. |
1251 | */ | 1265 | */ |
1252 | rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1266 | rt2500pci_write_tx_desc(entry, txdesc); |
1253 | 1267 | ||
1254 | /* | 1268 | /* |
1255 | * Dump beacon to userspace through debugfs. | 1269 | * Dump beacon to userspace through debugfs. |
@@ -1265,24 +1279,24 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1265 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1279 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1266 | } | 1280 | } |
1267 | 1281 | ||
1268 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1282 | static void rt2500pci_kick_tx_queue(struct data_queue *queue) |
1269 | const enum data_queue_qid queue) | ||
1270 | { | 1283 | { |
1284 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1271 | u32 reg; | 1285 | u32 reg; |
1272 | 1286 | ||
1273 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1287 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
1274 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); | 1288 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); |
1275 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); | 1289 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); |
1276 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); | 1290 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); |
1277 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1291 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1278 | } | 1292 | } |
1279 | 1293 | ||
1280 | static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 1294 | static void rt2500pci_kill_tx_queue(struct data_queue *queue) |
1281 | const enum data_queue_qid qid) | ||
1282 | { | 1295 | { |
1296 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1283 | u32 reg; | 1297 | u32 reg; |
1284 | 1298 | ||
1285 | if (qid == QID_BEACON) { | 1299 | if (queue->qid == QID_BEACON) { |
1286 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 1300 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); |
1287 | } else { | 1301 | } else { |
1288 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1302 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
@@ -1795,19 +1809,23 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1795 | /* | 1809 | /* |
1796 | * Create channel information array | 1810 | * Create channel information array |
1797 | */ | 1811 | */ |
1798 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 1812 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
1799 | if (!info) | 1813 | if (!info) |
1800 | return -ENOMEM; | 1814 | return -ENOMEM; |
1801 | 1815 | ||
1802 | spec->channels_info = info; | 1816 | spec->channels_info = info; |
1803 | 1817 | ||
1804 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | 1818 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); |
1805 | for (i = 0; i < 14; i++) | 1819 | for (i = 0; i < 14; i++) { |
1806 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 1820 | info[i].max_power = MAX_TXPOWER; |
1821 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
1822 | } | ||
1807 | 1823 | ||
1808 | if (spec->num_channels > 14) { | 1824 | if (spec->num_channels > 14) { |
1809 | for (i = 14; i < spec->num_channels; i++) | 1825 | for (i = 14; i < spec->num_channels; i++) { |
1810 | info[i].tx_power1 = DEFAULT_TXPOWER; | 1826 | info[i].max_power = MAX_TXPOWER; |
1827 | info[i].default_power1 = DEFAULT_TXPOWER; | ||
1828 | } | ||
1811 | } | 1829 | } |
1812 | 1830 | ||
1813 | return 0; | 1831 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index cdaf93f48263..6e94356265b3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -355,7 +355,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
355 | * it is known that not work at least on some hardware. | 355 | * it is known that not work at least on some hardware. |
356 | * SW crypto will be used in that case. | 356 | * SW crypto will be used in that case. |
357 | */ | 357 | */ |
358 | if (key->alg == ALG_WEP && key->keyidx != 0) | 358 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || |
359 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | ||
360 | key->keyidx != 0) | ||
359 | return -EOPNOTSUPP; | 361 | return -EOPNOTSUPP; |
360 | 362 | ||
361 | /* | 363 | /* |
@@ -492,24 +494,34 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
492 | } | 494 | } |
493 | 495 | ||
494 | static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, | 496 | static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, |
495 | struct rt2x00lib_erp *erp) | 497 | struct rt2x00lib_erp *erp, |
498 | u32 changed) | ||
496 | { | 499 | { |
497 | u16 reg; | 500 | u16 reg; |
498 | 501 | ||
499 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); | 502 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
500 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 503 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); |
501 | !!erp->short_preamble); | 504 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
502 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 505 | !!erp->short_preamble); |
506 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | ||
507 | } | ||
503 | 508 | ||
504 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates); | 509 | if (changed & BSS_CHANGED_BASIC_RATES) |
510 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, | ||
511 | erp->basic_rates); | ||
505 | 512 | ||
506 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 513 | if (changed & BSS_CHANGED_BEACON_INT) { |
507 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, erp->beacon_int * 4); | 514 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
508 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 515 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, |
516 | erp->beacon_int * 4); | ||
517 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | ||
518 | } | ||
509 | 519 | ||
510 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); | 520 | if (changed & BSS_CHANGED_ERP_SLOT) { |
511 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); | 521 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); |
512 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); | 522 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); |
523 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); | ||
524 | } | ||
513 | } | 525 | } |
514 | 526 | ||
515 | static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev, | 527 | static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev, |
@@ -1039,12 +1051,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1039 | /* | 1051 | /* |
1040 | * TX descriptor initialization | 1052 | * TX descriptor initialization |
1041 | */ | 1053 | */ |
1042 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1054 | static void rt2500usb_write_tx_desc(struct queue_entry *entry, |
1043 | struct sk_buff *skb, | ||
1044 | struct txentry_desc *txdesc) | 1055 | struct txentry_desc *txdesc) |
1045 | { | 1056 | { |
1046 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1057 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1047 | __le32 *txd = (__le32 *) skb->data; | 1058 | __le32 *txd = (__le32 *) entry->skb->data; |
1048 | u32 word; | 1059 | u32 word; |
1049 | 1060 | ||
1050 | /* | 1061 | /* |
@@ -1127,7 +1138,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, | |||
1127 | /* | 1138 | /* |
1128 | * Write the TX descriptor for the beacon. | 1139 | * Write the TX descriptor for the beacon. |
1129 | */ | 1140 | */ |
1130 | rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1141 | rt2500usb_write_tx_desc(entry, txdesc); |
1131 | 1142 | ||
1132 | /* | 1143 | /* |
1133 | * Dump beacon to userspace through debugfs. | 1144 | * Dump beacon to userspace through debugfs. |
@@ -1195,6 +1206,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) | |||
1195 | return length; | 1206 | return length; |
1196 | } | 1207 | } |
1197 | 1208 | ||
1209 | static void rt2500usb_kill_tx_queue(struct data_queue *queue) | ||
1210 | { | ||
1211 | if (queue->qid == QID_BEACON) | ||
1212 | rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0); | ||
1213 | |||
1214 | rt2x00usb_kill_tx_queue(queue); | ||
1215 | } | ||
1216 | |||
1198 | /* | 1217 | /* |
1199 | * RX control handlers | 1218 | * RX control handlers |
1200 | */ | 1219 | */ |
@@ -1698,19 +1717,23 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1698 | /* | 1717 | /* |
1699 | * Create channel information array | 1718 | * Create channel information array |
1700 | */ | 1719 | */ |
1701 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 1720 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
1702 | if (!info) | 1721 | if (!info) |
1703 | return -ENOMEM; | 1722 | return -ENOMEM; |
1704 | 1723 | ||
1705 | spec->channels_info = info; | 1724 | spec->channels_info = info; |
1706 | 1725 | ||
1707 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | 1726 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); |
1708 | for (i = 0; i < 14; i++) | 1727 | for (i = 0; i < 14; i++) { |
1709 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 1728 | info[i].max_power = MAX_TXPOWER; |
1729 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
1730 | } | ||
1710 | 1731 | ||
1711 | if (spec->num_channels > 14) { | 1732 | if (spec->num_channels > 14) { |
1712 | for (i = 14; i < spec->num_channels; i++) | 1733 | for (i = 14; i < spec->num_channels; i++) { |
1713 | info[i].tx_power1 = DEFAULT_TXPOWER; | 1734 | info[i].max_power = MAX_TXPOWER; |
1735 | info[i].default_power1 = DEFAULT_TXPOWER; | ||
1736 | } | ||
1714 | } | 1737 | } |
1715 | 1738 | ||
1716 | return 0; | 1739 | return 0; |
@@ -1789,7 +1812,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1789 | .write_beacon = rt2500usb_write_beacon, | 1812 | .write_beacon = rt2500usb_write_beacon, |
1790 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1813 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1791 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 1814 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
1792 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 1815 | .kill_tx_queue = rt2500usb_kill_tx_queue, |
1793 | .fill_rxdone = rt2500usb_fill_rxdone, | 1816 | .fill_rxdone = rt2500usb_fill_rxdone, |
1794 | .config_shared_key = rt2500usb_config_key, | 1817 | .config_shared_key = rt2500usb_config_key, |
1795 | .config_pairwise_key = rt2500usb_config_key, | 1818 | .config_pairwise_key = rt2500usb_config_key, |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ed4ebcdde7c9..2edc7742a7e9 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -639,6 +639,18 @@ | |||
639 | #define LED_CFG_LED_POLAR FIELD32(0x40000000) | 639 | #define LED_CFG_LED_POLAR FIELD32(0x40000000) |
640 | 640 | ||
641 | /* | 641 | /* |
642 | * AMPDU_BA_WINSIZE: Force BlockAck window size | ||
643 | * FORCE_WINSIZE_ENABLE: | ||
644 | * 0: Disable forcing of BlockAck window size | ||
645 | * 1: Enable forcing of BlockAck window size, overwrites values BlockAck | ||
646 | * window size values in the TXWI | ||
647 | * FORCE_WINSIZE: BlockAck window size | ||
648 | */ | ||
649 | #define AMPDU_BA_WINSIZE 0x1040 | ||
650 | #define AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE FIELD32(0x00000020) | ||
651 | #define AMPDU_BA_WINSIZE_FORCE_WINSIZE FIELD32(0x0000001f) | ||
652 | |||
653 | /* | ||
642 | * XIFS_TIME_CFG: MAC timing | 654 | * XIFS_TIME_CFG: MAC timing |
643 | * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX | 655 | * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX |
644 | * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX | 656 | * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX |
@@ -1318,7 +1330,25 @@ | |||
1318 | #define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000) | 1330 | #define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000) |
1319 | 1331 | ||
1320 | /* | 1332 | /* |
1321 | * TX_STA_FIFO: TX Result for specific PID status fifo register | 1333 | * TX_STA_FIFO: TX Result for specific PID status fifo register. |
1334 | * | ||
1335 | * This register is implemented as FIFO with 16 entries in the HW. Each | ||
1336 | * register read fetches the next tx result. If the FIFO is full because | ||
1337 | * it wasn't read fast enough after the according interrupt (TX_FIFO_STATUS) | ||
1338 | * triggered, the hw seems to simply drop further tx results. | ||
1339 | * | ||
1340 | * VALID: 1: this tx result is valid | ||
1341 | * 0: no valid tx result -> driver should stop reading | ||
1342 | * PID_TYPE: The PID latched from the PID field in the TXWI, can be used | ||
1343 | * to match a frame with its tx result (even though the PID is | ||
1344 | * only 4 bits wide). | ||
1345 | * TX_SUCCESS: Indicates tx success (1) or failure (0) | ||
1346 | * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) | ||
1347 | * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) | ||
1348 | * WCID: The wireless client ID. | ||
1349 | * MCS: The tx rate used during the last transmission of this frame, be it | ||
1350 | * successful or not. | ||
1351 | * PHYMODE: The phymode used for the transmission. | ||
1322 | */ | 1352 | */ |
1323 | #define TX_STA_FIFO 0x1718 | 1353 | #define TX_STA_FIFO 0x1718 |
1324 | #define TX_STA_FIFO_VALID FIELD32(0x00000001) | 1354 | #define TX_STA_FIFO_VALID FIELD32(0x00000001) |
@@ -1841,6 +1871,13 @@ struct mac_iveiv_entry { | |||
1841 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) | 1871 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) |
1842 | 1872 | ||
1843 | /* | 1873 | /* |
1874 | * EEPROM Maximum TX power values | ||
1875 | */ | ||
1876 | #define EEPROM_MAX_TX_POWER 0x0027 | ||
1877 | #define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) | ||
1878 | #define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) | ||
1879 | |||
1880 | /* | ||
1844 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. | 1881 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. |
1845 | * This is delta in 40MHZ. | 1882 | * This is delta in 40MHZ. |
1846 | * VALUE: Tx Power dalta value (MAX=4) | 1883 | * VALUE: Tx Power dalta value (MAX=4) |
@@ -1928,6 +1965,8 @@ struct mac_iveiv_entry { | |||
1928 | * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs | 1965 | * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs |
1929 | * BW: Channel bandwidth 20MHz or 40 MHz | 1966 | * BW: Channel bandwidth 20MHz or 40 MHz |
1930 | * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED | 1967 | * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED |
1968 | * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will | ||
1969 | * aggregate consecutive frames with the same RA and QoS TID. | ||
1931 | */ | 1970 | */ |
1932 | #define TXWI_W0_FRAG FIELD32(0x00000001) | 1971 | #define TXWI_W0_FRAG FIELD32(0x00000001) |
1933 | #define TXWI_W0_MIMO_PS FIELD32(0x00000002) | 1972 | #define TXWI_W0_MIMO_PS FIELD32(0x00000002) |
@@ -1945,6 +1984,15 @@ struct mac_iveiv_entry { | |||
1945 | 1984 | ||
1946 | /* | 1985 | /* |
1947 | * Word1 | 1986 | * Word1 |
1987 | * ACK: 0: No Ack needed, 1: Ack needed | ||
1988 | * NSEQ: 0: Don't assign hw sequence number, 1: Assign hw sequence number | ||
1989 | * BW_WIN_SIZE: BA windows size of the recipient | ||
1990 | * WIRELESS_CLI_ID: Client ID for WCID table access | ||
1991 | * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame | ||
1992 | * PACKETID: Will be latched into the TX_STA_FIFO register once the according | ||
1993 | * frame was processed. If multiple frames are aggregated together | ||
1994 | * (AMPDU==1) the reported tx status will always contain the packet | ||
1995 | * id of the first frame. 0: Don't report tx status for this frame. | ||
1948 | */ | 1996 | */ |
1949 | #define TXWI_W1_ACK FIELD32(0x00000001) | 1997 | #define TXWI_W1_ACK FIELD32(0x00000001) |
1950 | #define TXWI_W1_NSEQ FIELD32(0x00000002) | 1998 | #define TXWI_W1_NSEQ FIELD32(0x00000002) |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b66e0fd8f0fa..3bb67492d754 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> | ||
2 | Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com> | 3 | Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 4 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> |
4 | Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> | 5 | Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> |
@@ -254,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
254 | } | 255 | } |
255 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); | 256 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); |
256 | 257 | ||
258 | int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) | ||
259 | { | ||
260 | unsigned int i = 0; | ||
261 | u32 reg; | ||
262 | |||
263 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
264 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
265 | if (reg && reg != ~0) | ||
266 | return 0; | ||
267 | msleep(1); | ||
268 | } | ||
269 | |||
270 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
271 | return -EBUSY; | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); | ||
274 | |||
257 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | 275 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) |
258 | { | 276 | { |
259 | unsigned int i; | 277 | unsigned int i; |
@@ -367,19 +385,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
367 | u32 reg; | 385 | u32 reg; |
368 | 386 | ||
369 | /* | 387 | /* |
370 | * Wait for stable hardware. | 388 | * If driver doesn't wake up firmware here, |
389 | * rt2800_load_firmware will hang forever when interface is up again. | ||
371 | */ | 390 | */ |
372 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 391 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); |
373 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
374 | if (reg && reg != ~0) | ||
375 | break; | ||
376 | msleep(1); | ||
377 | } | ||
378 | 392 | ||
379 | if (i == REGISTER_BUSY_COUNT) { | 393 | /* |
380 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 394 | * Wait for stable hardware. |
395 | */ | ||
396 | if (rt2800_wait_csr_ready(rt2x00dev)) | ||
381 | return -EBUSY; | 397 | return -EBUSY; |
382 | } | ||
383 | 398 | ||
384 | if (rt2x00_is_pci(rt2x00dev)) | 399 | if (rt2x00_is_pci(rt2x00dev)) |
385 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | 400 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); |
@@ -427,8 +442,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
427 | } | 442 | } |
428 | EXPORT_SYMBOL_GPL(rt2800_load_firmware); | 443 | EXPORT_SYMBOL_GPL(rt2800_load_firmware); |
429 | 444 | ||
430 | void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | 445 | void rt2800_write_tx_data(struct queue_entry *entry, |
446 | struct txentry_desc *txdesc) | ||
431 | { | 447 | { |
448 | __le32 *txwi = rt2800_drv_get_txwi(entry); | ||
432 | u32 word; | 449 | u32 word; |
433 | 450 | ||
434 | /* | 451 | /* |
@@ -437,7 +454,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | |||
437 | rt2x00_desc_read(txwi, 0, &word); | 454 | rt2x00_desc_read(txwi, 0, &word); |
438 | rt2x00_set_field32(&word, TXWI_W0_FRAG, | 455 | rt2x00_set_field32(&word, TXWI_W0_FRAG, |
439 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | 456 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
440 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); | 457 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, |
458 | test_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags)); | ||
441 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); | 459 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); |
442 | rt2x00_set_field32(&word, TXWI_W0_TS, | 460 | rt2x00_set_field32(&word, TXWI_W0_TS, |
443 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 461 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
@@ -465,7 +483,7 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | |||
465 | txdesc->key_idx : 0xff); | 483 | txdesc->key_idx : 0xff); |
466 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 484 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
467 | txdesc->length); | 485 | txdesc->length); |
468 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); | 486 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); |
469 | rt2x00_desc_write(txwi, 1, word); | 487 | rt2x00_desc_write(txwi, 1, word); |
470 | 488 | ||
471 | /* | 489 | /* |
@@ -478,7 +496,7 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | |||
478 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | 496 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); |
479 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | 497 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); |
480 | } | 498 | } |
481 | EXPORT_SYMBOL_GPL(rt2800_write_txwi); | 499 | EXPORT_SYMBOL_GPL(rt2800_write_tx_data); |
482 | 500 | ||
483 | static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) | 501 | static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) |
484 | { | 502 | { |
@@ -490,7 +508,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) | |||
490 | u8 offset1; | 508 | u8 offset1; |
491 | u8 offset2; | 509 | u8 offset2; |
492 | 510 | ||
493 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) { | 511 | if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { |
494 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); | 512 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); |
495 | offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); | 513 | offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); |
496 | offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); | 514 | offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); |
@@ -569,6 +587,148 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |||
569 | } | 587 | } |
570 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 588 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
571 | 589 | ||
590 | static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) | ||
591 | { | ||
592 | __le32 *txwi; | ||
593 | u32 word; | ||
594 | int wcid, ack, pid; | ||
595 | int tx_wcid, tx_ack, tx_pid; | ||
596 | |||
597 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
598 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
599 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
600 | |||
601 | /* | ||
602 | * This frames has returned with an IO error, | ||
603 | * so the status report is not intended for this | ||
604 | * frame. | ||
605 | */ | ||
606 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { | ||
607 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
608 | return false; | ||
609 | } | ||
610 | |||
611 | /* | ||
612 | * Validate if this TX status report is intended for | ||
613 | * this entry by comparing the WCID/ACK/PID fields. | ||
614 | */ | ||
615 | txwi = rt2800_drv_get_txwi(entry); | ||
616 | |||
617 | rt2x00_desc_read(txwi, 1, &word); | ||
618 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
619 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
620 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
621 | |||
622 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { | ||
623 | WARNING(entry->queue->rt2x00dev, | ||
624 | "TX status report missed for queue %d entry %d\n", | ||
625 | entry->queue->qid, entry->entry_idx); | ||
626 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | ||
627 | return false; | ||
628 | } | ||
629 | |||
630 | return true; | ||
631 | } | ||
632 | |||
633 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | ||
634 | { | ||
635 | struct data_queue *queue; | ||
636 | struct queue_entry *entry; | ||
637 | __le32 *txwi; | ||
638 | struct txdone_entry_desc txdesc; | ||
639 | u32 word; | ||
640 | u32 reg; | ||
641 | u16 mcs, real_mcs; | ||
642 | u8 pid; | ||
643 | int i; | ||
644 | |||
645 | /* | ||
646 | * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO | ||
647 | * at most X times and also stop processing once the TX_STA_FIFO_VALID | ||
648 | * flag is not set anymore. | ||
649 | * | ||
650 | * The legacy drivers use X=TX_RING_SIZE but state in a comment | ||
651 | * that the TX_STA_FIFO stack has a size of 16. We stick to our | ||
652 | * tx ring size for now. | ||
653 | */ | ||
654 | for (i = 0; i < TX_ENTRIES; i++) { | ||
655 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); | ||
656 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | ||
657 | break; | ||
658 | |||
659 | /* | ||
660 | * Skip this entry when it contains an invalid | ||
661 | * queue identication number. | ||
662 | */ | ||
663 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; | ||
664 | if (pid >= QID_RX) | ||
665 | continue; | ||
666 | |||
667 | queue = rt2x00queue_get_queue(rt2x00dev, pid); | ||
668 | if (unlikely(!queue)) | ||
669 | continue; | ||
670 | |||
671 | /* | ||
672 | * Inside each queue, we process each entry in a chronological | ||
673 | * order. We first check that the queue is not empty. | ||
674 | */ | ||
675 | entry = NULL; | ||
676 | txwi = NULL; | ||
677 | while (!rt2x00queue_empty(queue)) { | ||
678 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
679 | if (rt2800_txdone_entry_check(entry, reg)) | ||
680 | break; | ||
681 | } | ||
682 | |||
683 | if (!entry || rt2x00queue_empty(queue)) | ||
684 | break; | ||
685 | |||
686 | |||
687 | /* | ||
688 | * Obtain the status about this packet. | ||
689 | */ | ||
690 | txdesc.flags = 0; | ||
691 | txwi = rt2800_drv_get_txwi(entry); | ||
692 | rt2x00_desc_read(txwi, 0, &word); | ||
693 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | ||
694 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | ||
695 | |||
696 | /* | ||
697 | * Ralink has a retry mechanism using a global fallback | ||
698 | * table. We setup this fallback table to try the immediate | ||
699 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field | ||
700 | * always contains the MCS used for the last transmission, be | ||
701 | * it successful or not. | ||
702 | */ | ||
703 | if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { | ||
704 | /* | ||
705 | * Transmission succeeded. The number of retries is | ||
706 | * mcs - real_mcs | ||
707 | */ | ||
708 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
709 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
710 | } else { | ||
711 | /* | ||
712 | * Transmission failed. The number of retries is | ||
713 | * always 7 in this case (for a total number of 8 | ||
714 | * frames sent). | ||
715 | */ | ||
716 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
717 | txdesc.retry = rt2x00dev->long_retry; | ||
718 | } | ||
719 | |||
720 | /* | ||
721 | * the frame was retried at least once | ||
722 | * -> hw used fallback rates | ||
723 | */ | ||
724 | if (txdesc.retry) | ||
725 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
726 | |||
727 | rt2x00lib_txdone(entry, &txdesc); | ||
728 | } | ||
729 | } | ||
730 | EXPORT_SYMBOL_GPL(rt2800_txdone); | ||
731 | |||
572 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | 732 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) |
573 | { | 733 | { |
574 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 734 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
@@ -600,7 +760,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
600 | /* | 760 | /* |
601 | * Add the TXWI for the beacon to the skb. | 761 | * Add the TXWI for the beacon to the skb. |
602 | */ | 762 | */ |
603 | rt2800_write_txwi((__le32 *)entry->skb->data, txdesc); | 763 | rt2800_write_tx_data(entry, txdesc); |
604 | 764 | ||
605 | /* | 765 | /* |
606 | * Dump beacon to userspace through debugfs. | 766 | * Dump beacon to userspace through debugfs. |
@@ -975,19 +1135,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
975 | } | 1135 | } |
976 | 1136 | ||
977 | if (flags & CONFIG_UPDATE_MAC) { | 1137 | if (flags & CONFIG_UPDATE_MAC) { |
978 | reg = le32_to_cpu(conf->mac[1]); | 1138 | if (!is_zero_ether_addr((const u8 *)conf->mac)) { |
979 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); | 1139 | reg = le32_to_cpu(conf->mac[1]); |
980 | conf->mac[1] = cpu_to_le32(reg); | 1140 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); |
1141 | conf->mac[1] = cpu_to_le32(reg); | ||
1142 | } | ||
981 | 1143 | ||
982 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, | 1144 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, |
983 | conf->mac, sizeof(conf->mac)); | 1145 | conf->mac, sizeof(conf->mac)); |
984 | } | 1146 | } |
985 | 1147 | ||
986 | if (flags & CONFIG_UPDATE_BSSID) { | 1148 | if (flags & CONFIG_UPDATE_BSSID) { |
987 | reg = le32_to_cpu(conf->bssid[1]); | 1149 | if (!is_zero_ether_addr((const u8 *)conf->bssid)) { |
988 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); | 1150 | reg = le32_to_cpu(conf->bssid[1]); |
989 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); | 1151 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); |
990 | conf->bssid[1] = cpu_to_le32(reg); | 1152 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); |
1153 | conf->bssid[1] = cpu_to_le32(reg); | ||
1154 | } | ||
991 | 1155 | ||
992 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, | 1156 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, |
993 | conf->bssid, sizeof(conf->bssid)); | 1157 | conf->bssid, sizeof(conf->bssid)); |
@@ -995,38 +1159,50 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
995 | } | 1159 | } |
996 | EXPORT_SYMBOL_GPL(rt2800_config_intf); | 1160 | EXPORT_SYMBOL_GPL(rt2800_config_intf); |
997 | 1161 | ||
998 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp) | 1162 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, |
1163 | u32 changed) | ||
999 | { | 1164 | { |
1000 | u32 reg; | 1165 | u32 reg; |
1001 | 1166 | ||
1002 | rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); | 1167 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
1003 | rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, | 1168 | rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); |
1004 | !!erp->short_preamble); | 1169 | rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, |
1005 | rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, | 1170 | !!erp->short_preamble); |
1006 | !!erp->short_preamble); | 1171 | rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, |
1007 | rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); | 1172 | !!erp->short_preamble); |
1173 | rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); | ||
1174 | } | ||
1008 | 1175 | ||
1009 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | 1176 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
1010 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, | 1177 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); |
1011 | erp->cts_protection ? 2 : 0); | 1178 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, |
1012 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | 1179 | erp->cts_protection ? 2 : 0); |
1180 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
1181 | } | ||
1013 | 1182 | ||
1014 | rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, | 1183 | if (changed & BSS_CHANGED_BASIC_RATES) { |
1015 | erp->basic_rates); | 1184 | rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, |
1016 | rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); | 1185 | erp->basic_rates); |
1186 | rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); | ||
1187 | } | ||
1017 | 1188 | ||
1018 | rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); | 1189 | if (changed & BSS_CHANGED_ERP_SLOT) { |
1019 | rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time); | 1190 | rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); |
1020 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); | 1191 | rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, |
1192 | erp->slot_time); | ||
1193 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); | ||
1021 | 1194 | ||
1022 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); | 1195 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); |
1023 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); | 1196 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); |
1024 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); | 1197 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); |
1198 | } | ||
1025 | 1199 | ||
1026 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 1200 | if (changed & BSS_CHANGED_BEACON_INT) { |
1027 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | 1201 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
1028 | erp->beacon_int * 16); | 1202 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, |
1029 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 1203 | erp->beacon_int * 16); |
1204 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
1205 | } | ||
1030 | } | 1206 | } |
1031 | EXPORT_SYMBOL_GPL(rt2800_config_erp); | 1207 | EXPORT_SYMBOL_GPL(rt2800_config_erp); |
1032 | 1208 | ||
@@ -1120,27 +1296,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, | |||
1120 | * double meaning, and we should set a 7DBm boost flag. | 1296 | * double meaning, and we should set a 7DBm boost flag. |
1121 | */ | 1297 | */ |
1122 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, | 1298 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, |
1123 | (info->tx_power1 >= 0)); | 1299 | (info->default_power1 >= 0)); |
1124 | 1300 | ||
1125 | if (info->tx_power1 < 0) | 1301 | if (info->default_power1 < 0) |
1126 | info->tx_power1 += 7; | 1302 | info->default_power1 += 7; |
1127 | 1303 | ||
1128 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, | 1304 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1); |
1129 | TXPOWER_A_TO_DEV(info->tx_power1)); | ||
1130 | 1305 | ||
1131 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, | 1306 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, |
1132 | (info->tx_power2 >= 0)); | 1307 | (info->default_power2 >= 0)); |
1133 | 1308 | ||
1134 | if (info->tx_power2 < 0) | 1309 | if (info->default_power2 < 0) |
1135 | info->tx_power2 += 7; | 1310 | info->default_power2 += 7; |
1136 | 1311 | ||
1137 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, | 1312 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2); |
1138 | TXPOWER_A_TO_DEV(info->tx_power2)); | ||
1139 | } else { | 1313 | } else { |
1140 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, | 1314 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1); |
1141 | TXPOWER_G_TO_DEV(info->tx_power1)); | 1315 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2); |
1142 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, | ||
1143 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1144 | } | 1316 | } |
1145 | 1317 | ||
1146 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); | 1318 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); |
@@ -1180,13 +1352,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1180 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | 1352 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); |
1181 | 1353 | ||
1182 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); | 1354 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); |
1183 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | 1355 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1); |
1184 | TXPOWER_G_TO_DEV(info->tx_power1)); | ||
1185 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | 1356 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); |
1186 | 1357 | ||
1187 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); | 1358 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); |
1188 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | 1359 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); |
1189 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1190 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); | 1360 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); |
1191 | 1361 | ||
1192 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | 1362 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); |
@@ -1210,10 +1380,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1210 | unsigned int tx_pin; | 1380 | unsigned int tx_pin; |
1211 | u8 bbp; | 1381 | u8 bbp; |
1212 | 1382 | ||
1383 | if (rf->channel <= 14) { | ||
1384 | info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); | ||
1385 | info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); | ||
1386 | } else { | ||
1387 | info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); | ||
1388 | info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); | ||
1389 | } | ||
1390 | |||
1213 | if (rt2x00_rf(rt2x00dev, RF2020) || | 1391 | if (rt2x00_rf(rt2x00dev, RF2020) || |
1214 | rt2x00_rf(rt2x00dev, RF3020) || | 1392 | rt2x00_rf(rt2x00dev, RF3020) || |
1215 | rt2x00_rf(rt2x00dev, RF3021) || | 1393 | rt2x00_rf(rt2x00dev, RF3021) || |
1216 | rt2x00_rf(rt2x00dev, RF3022)) | 1394 | rt2x00_rf(rt2x00dev, RF3022) || |
1395 | rt2x00_rf(rt2x00dev, RF3052)) | ||
1217 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1396 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
1218 | else | 1397 | else |
1219 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | 1398 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); |
@@ -1536,7 +1715,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); | |||
1536 | /* | 1715 | /* |
1537 | * Initialization functions. | 1716 | * Initialization functions. |
1538 | */ | 1717 | */ |
1539 | int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | 1718 | static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) |
1540 | { | 1719 | { |
1541 | u32 reg; | 1720 | u32 reg; |
1542 | u16 eeprom; | 1721 | u16 eeprom; |
@@ -1886,6 +2065,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1886 | rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg); | 2065 | rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg); |
1887 | 2066 | ||
1888 | /* | 2067 | /* |
2068 | * Do not force the BA window size, we use the TXWI to set it | ||
2069 | */ | ||
2070 | rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, ®); | ||
2071 | rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0); | ||
2072 | rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0); | ||
2073 | rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg); | ||
2074 | |||
2075 | /* | ||
1889 | * We must clear the error counters. | 2076 | * We must clear the error counters. |
1890 | * These registers are cleared on read, | 2077 | * These registers are cleared on read, |
1891 | * so we may pass a useless variable to store the value. | 2078 | * so we may pass a useless variable to store the value. |
@@ -1906,7 +2093,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1906 | 2093 | ||
1907 | return 0; | 2094 | return 0; |
1908 | } | 2095 | } |
1909 | EXPORT_SYMBOL_GPL(rt2800_init_registers); | ||
1910 | 2096 | ||
1911 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) | 2097 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) |
1912 | { | 2098 | { |
@@ -1949,7 +2135,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
1949 | return -EACCES; | 2135 | return -EACCES; |
1950 | } | 2136 | } |
1951 | 2137 | ||
1952 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | 2138 | static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) |
1953 | { | 2139 | { |
1954 | unsigned int i; | 2140 | unsigned int i; |
1955 | u16 eeprom; | 2141 | u16 eeprom; |
@@ -2044,7 +2230,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2044 | 2230 | ||
2045 | return 0; | 2231 | return 0; |
2046 | } | 2232 | } |
2047 | EXPORT_SYMBOL_GPL(rt2800_init_bbp); | ||
2048 | 2233 | ||
2049 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | 2234 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, |
2050 | bool bw40, u8 rfcsr24, u8 filter_target) | 2235 | bool bw40, u8 rfcsr24, u8 filter_target) |
@@ -2106,7 +2291,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
2106 | return rfcsr24; | 2291 | return rfcsr24; |
2107 | } | 2292 | } |
2108 | 2293 | ||
2109 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | 2294 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) |
2110 | { | 2295 | { |
2111 | u8 rfcsr; | 2296 | u8 rfcsr; |
2112 | u8 bbp; | 2297 | u8 bbp; |
@@ -2360,7 +2545,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2360 | 2545 | ||
2361 | return 0; | 2546 | return 0; |
2362 | } | 2547 | } |
2363 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); | 2548 | |
2549 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
2550 | { | ||
2551 | u32 reg; | ||
2552 | u16 word; | ||
2553 | |||
2554 | /* | ||
2555 | * Initialize all registers. | ||
2556 | */ | ||
2557 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | ||
2558 | rt2800_init_registers(rt2x00dev) || | ||
2559 | rt2800_init_bbp(rt2x00dev) || | ||
2560 | rt2800_init_rfcsr(rt2x00dev))) | ||
2561 | return -EIO; | ||
2562 | |||
2563 | /* | ||
2564 | * Send signal to firmware during boot time. | ||
2565 | */ | ||
2566 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
2567 | |||
2568 | if (rt2x00_is_usb(rt2x00dev) && | ||
2569 | (rt2x00_rt(rt2x00dev, RT3070) || | ||
2570 | rt2x00_rt(rt2x00dev, RT3071) || | ||
2571 | rt2x00_rt(rt2x00dev, RT3572))) { | ||
2572 | udelay(200); | ||
2573 | rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); | ||
2574 | udelay(10); | ||
2575 | } | ||
2576 | |||
2577 | /* | ||
2578 | * Enable RX. | ||
2579 | */ | ||
2580 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2581 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
2582 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
2583 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2584 | |||
2585 | udelay(50); | ||
2586 | |||
2587 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
2588 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
2589 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
2590 | rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); | ||
2591 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
2592 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
2593 | |||
2594 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2595 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
2596 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
2597 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2598 | |||
2599 | /* | ||
2600 | * Initialize LED control | ||
2601 | */ | ||
2602 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
2603 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
2604 | word & 0xff, (word >> 8) & 0xff); | ||
2605 | |||
2606 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
2607 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
2608 | word & 0xff, (word >> 8) & 0xff); | ||
2609 | |||
2610 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
2611 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
2612 | word & 0xff, (word >> 8) & 0xff); | ||
2613 | |||
2614 | return 0; | ||
2615 | } | ||
2616 | EXPORT_SYMBOL_GPL(rt2800_enable_radio); | ||
2617 | |||
2618 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
2619 | { | ||
2620 | u32 reg; | ||
2621 | |||
2622 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
2623 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
2624 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); | ||
2625 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
2626 | rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); | ||
2627 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
2628 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
2629 | |||
2630 | /* Wait for DMA, ignore error */ | ||
2631 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
2632 | |||
2633 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2634 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); | ||
2635 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
2636 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2637 | |||
2638 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
2639 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
2640 | } | ||
2641 | EXPORT_SYMBOL_GPL(rt2800_disable_radio); | ||
2364 | 2642 | ||
2365 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) | 2643 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) |
2366 | { | 2644 | { |
@@ -2516,6 +2794,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2516 | default_lna_gain); | 2794 | default_lna_gain); |
2517 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | 2795 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); |
2518 | 2796 | ||
2797 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); | ||
2798 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) | ||
2799 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); | ||
2800 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) | ||
2801 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); | ||
2802 | rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); | ||
2803 | |||
2519 | return 0; | 2804 | return 0; |
2520 | } | 2805 | } |
2521 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); | 2806 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); |
@@ -2755,9 +3040,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2755 | { | 3040 | { |
2756 | struct hw_mode_spec *spec = &rt2x00dev->spec; | 3041 | struct hw_mode_spec *spec = &rt2x00dev->spec; |
2757 | struct channel_info *info; | 3042 | struct channel_info *info; |
2758 | char *tx_power1; | 3043 | char *default_power1; |
2759 | char *tx_power2; | 3044 | char *default_power2; |
2760 | unsigned int i; | 3045 | unsigned int i; |
3046 | unsigned short max_power; | ||
2761 | u16 eeprom; | 3047 | u16 eeprom; |
2762 | 3048 | ||
2763 | /* | 3049 | /* |
@@ -2865,27 +3151,32 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2865 | /* | 3151 | /* |
2866 | * Create channel information array | 3152 | * Create channel information array |
2867 | */ | 3153 | */ |
2868 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 3154 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
2869 | if (!info) | 3155 | if (!info) |
2870 | return -ENOMEM; | 3156 | return -ENOMEM; |
2871 | 3157 | ||
2872 | spec->channels_info = info; | 3158 | spec->channels_info = info; |
2873 | 3159 | ||
2874 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | 3160 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); |
2875 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | 3161 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); |
3162 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
3163 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
2876 | 3164 | ||
2877 | for (i = 0; i < 14; i++) { | 3165 | for (i = 0; i < 14; i++) { |
2878 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | 3166 | info[i].max_power = max_power; |
2879 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | 3167 | info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); |
3168 | info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); | ||
2880 | } | 3169 | } |
2881 | 3170 | ||
2882 | if (spec->num_channels > 14) { | 3171 | if (spec->num_channels > 14) { |
2883 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | 3172 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); |
2884 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 3173 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); |
3174 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
2885 | 3175 | ||
2886 | for (i = 14; i < spec->num_channels; i++) { | 3176 | for (i = 14; i < spec->num_channels; i++) { |
2887 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | 3177 | info[i].max_power = max_power; |
2888 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | 3178 | info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); |
3179 | info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); | ||
2889 | } | 3180 | } |
2890 | } | 3181 | } |
2891 | 3182 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 091641e3c5e2..600c5eb25c41 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -1,4 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> | ||
3 | Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
2 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz | 4 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz |
3 | 5 | ||
4 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -44,6 +46,7 @@ struct rt2800_ops { | |||
44 | int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, | 46 | int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, |
45 | const u8 *data, const size_t len); | 47 | const u8 *data, const size_t len); |
46 | int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); | 48 | int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); |
49 | __le32 *(*drv_get_txwi)(struct queue_entry *entry); | ||
47 | }; | 50 | }; |
48 | 51 | ||
49 | static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, | 52 | static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, |
@@ -126,18 +129,31 @@ static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev) | |||
126 | return rt2800ops->drv_init_registers(rt2x00dev); | 129 | return rt2800ops->drv_init_registers(rt2x00dev); |
127 | } | 130 | } |
128 | 131 | ||
132 | static inline __le32 *rt2800_drv_get_txwi(struct queue_entry *entry) | ||
133 | { | ||
134 | const struct rt2800_ops *rt2800ops = entry->queue->rt2x00dev->ops->drv; | ||
135 | |||
136 | return rt2800ops->drv_get_txwi(entry); | ||
137 | } | ||
138 | |||
129 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | 139 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, |
130 | const u8 command, const u8 token, | 140 | const u8 command, const u8 token, |
131 | const u8 arg0, const u8 arg1); | 141 | const u8 arg0, const u8 arg1); |
132 | 142 | ||
143 | int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev); | ||
144 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); | ||
145 | |||
133 | int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, | 146 | int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, |
134 | const u8 *data, const size_t len); | 147 | const u8 *data, const size_t len); |
135 | int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | 148 | int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, |
136 | const u8 *data, const size_t len); | 149 | const u8 *data, const size_t len); |
137 | 150 | ||
138 | void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc); | 151 | void rt2800_write_tx_data(struct queue_entry *entry, |
152 | struct txentry_desc *txdesc); | ||
139 | void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); | 153 | void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); |
140 | 154 | ||
155 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev); | ||
156 | |||
141 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); | 157 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); |
142 | 158 | ||
143 | extern const struct rt2x00debug rt2800_rt2x00debug; | 159 | extern const struct rt2x00debug rt2800_rt2x00debug; |
@@ -153,7 +169,8 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, | |||
153 | const unsigned int filter_flags); | 169 | const unsigned int filter_flags); |
154 | void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | 170 | void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, |
155 | struct rt2x00intf_conf *conf, const unsigned int flags); | 171 | struct rt2x00intf_conf *conf, const unsigned int flags); |
156 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp); | 172 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, |
173 | u32 changed); | ||
157 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); | 174 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); |
158 | void rt2800_config(struct rt2x00_dev *rt2x00dev, | 175 | void rt2800_config(struct rt2x00_dev *rt2x00dev, |
159 | struct rt2x00lib_conf *libconf, | 176 | struct rt2x00lib_conf *libconf, |
@@ -163,10 +180,8 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); | |||
163 | void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, | 180 | void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, |
164 | const u32 count); | 181 | const u32 count); |
165 | 182 | ||
166 | int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); | 183 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); |
167 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); | 184 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); |
168 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); | ||
169 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); | ||
170 | 185 | ||
171 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); | 186 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); |
172 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); | 187 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 39b3846fa340..005ee153e0cc 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | 3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> |
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | 4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> |
5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | 5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> |
@@ -196,8 +196,6 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
196 | { | 196 | { |
197 | u32 reg; | 197 | u32 reg; |
198 | 198 | ||
199 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); | ||
200 | |||
201 | /* | 199 | /* |
202 | * enable Host program ram write selection | 200 | * enable Host program ram write selection |
203 | */ | 201 | */ |
@@ -344,24 +342,24 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
344 | } | 342 | } |
345 | 343 | ||
346 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | 344 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); |
347 | rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, mask); | 345 | rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); |
348 | rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, mask); | 346 | rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); |
349 | rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); | 347 | rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); |
350 | rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, mask); | 348 | rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, 0); |
351 | rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, mask); | 349 | rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, 0); |
352 | rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, mask); | 350 | rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, 0); |
353 | rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, mask); | 351 | rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, 0); |
354 | rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, mask); | 352 | rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, 0); |
355 | rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, mask); | 353 | rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, 0); |
356 | rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, mask); | 354 | rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, 0); |
357 | rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, mask); | 355 | rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, 0); |
358 | rt2x00_set_field32(®, INT_MASK_CSR_TBTT, mask); | 356 | rt2x00_set_field32(®, INT_MASK_CSR_TBTT, mask); |
359 | rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, mask); | 357 | rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, mask); |
360 | rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, mask); | 358 | rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, mask); |
361 | rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, mask); | 359 | rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, mask); |
362 | rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, mask); | 360 | rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); |
363 | rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, mask); | 361 | rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); |
364 | rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, mask); | 362 | rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); |
365 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 363 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); |
366 | } | 364 | } |
367 | 365 | ||
@@ -399,78 +397,18 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
399 | 397 | ||
400 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | 398 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) |
401 | { | 399 | { |
402 | u32 reg; | ||
403 | u16 word; | ||
404 | |||
405 | /* | ||
406 | * Initialize all registers. | ||
407 | */ | ||
408 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | 400 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || |
409 | rt2800pci_init_queues(rt2x00dev) || | 401 | rt2800pci_init_queues(rt2x00dev))) |
410 | rt2800_init_registers(rt2x00dev) || | ||
411 | rt2800_wait_wpdma_ready(rt2x00dev) || | ||
412 | rt2800_init_bbp(rt2x00dev) || | ||
413 | rt2800_init_rfcsr(rt2x00dev))) | ||
414 | return -EIO; | 402 | return -EIO; |
415 | 403 | ||
416 | /* | 404 | return rt2800_enable_radio(rt2x00dev); |
417 | * Send signal to firmware during boot time. | ||
418 | */ | ||
419 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
420 | |||
421 | /* | ||
422 | * Enable RX. | ||
423 | */ | ||
424 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
425 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
426 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
427 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
428 | |||
429 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
430 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
431 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
432 | rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); | ||
433 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
434 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
435 | |||
436 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
437 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
438 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
439 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
440 | |||
441 | /* | ||
442 | * Initialize LED control | ||
443 | */ | ||
444 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
445 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
446 | word & 0xff, (word >> 8) & 0xff); | ||
447 | |||
448 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
449 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
450 | word & 0xff, (word >> 8) & 0xff); | ||
451 | |||
452 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
453 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
454 | word & 0xff, (word >> 8) & 0xff); | ||
455 | |||
456 | return 0; | ||
457 | } | 405 | } |
458 | 406 | ||
459 | static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) | 407 | static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) |
460 | { | 408 | { |
461 | u32 reg; | 409 | u32 reg; |
462 | 410 | ||
463 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | 411 | rt2800_disable_radio(rt2x00dev); |
464 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
465 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); | ||
466 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
467 | rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); | ||
468 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
469 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
470 | |||
471 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); | ||
472 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
473 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
474 | 412 | ||
475 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); | 413 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); |
476 | 414 | ||
@@ -486,9 +424,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
486 | 424 | ||
487 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 425 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
488 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 426 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
489 | |||
490 | /* Wait for DMA, ignore error */ | ||
491 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
492 | } | 427 | } |
493 | 428 | ||
494 | static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, | 429 | static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, |
@@ -566,21 +501,16 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
566 | /* | 501 | /* |
567 | * TX descriptor initialization | 502 | * TX descriptor initialization |
568 | */ | 503 | */ |
569 | static void rt2800pci_write_tx_data(struct queue_entry* entry, | 504 | static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) |
570 | struct txentry_desc *txdesc) | ||
571 | { | 505 | { |
572 | __le32 *txwi = (__le32 *) entry->skb->data; | 506 | return (__le32 *) entry->skb->data; |
573 | |||
574 | rt2800_write_txwi(txwi, txdesc); | ||
575 | } | 507 | } |
576 | 508 | ||
577 | 509 | static void rt2800pci_write_tx_desc(struct queue_entry *entry, | |
578 | static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
579 | struct sk_buff *skb, | ||
580 | struct txentry_desc *txdesc) | 510 | struct txentry_desc *txdesc) |
581 | { | 511 | { |
582 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 512 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
583 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 513 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
584 | __le32 *txd = entry_priv->desc; | 514 | __le32 *txd = entry_priv->desc; |
585 | u32 word; | 515 | u32 word; |
586 | 516 | ||
@@ -600,7 +530,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
600 | rt2x00_desc_write(txd, 0, word); | 530 | rt2x00_desc_write(txd, 0, word); |
601 | 531 | ||
602 | rt2x00_desc_read(txd, 1, &word); | 532 | rt2x00_desc_read(txd, 1, &word); |
603 | rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len); | 533 | rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); |
604 | rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, | 534 | rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, |
605 | !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | 535 | !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
606 | rt2x00_set_field32(&word, TXD_W1_BURST, | 536 | rt2x00_set_field32(&word, TXD_W1_BURST, |
@@ -631,41 +561,35 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
631 | /* | 561 | /* |
632 | * TX data initialization | 562 | * TX data initialization |
633 | */ | 563 | */ |
634 | static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 564 | static void rt2800pci_kick_tx_queue(struct data_queue *queue) |
635 | const enum data_queue_qid queue_idx) | ||
636 | { | 565 | { |
637 | struct data_queue *queue; | 566 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
638 | unsigned int idx, qidx = 0; | 567 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
639 | 568 | unsigned int qidx = 0; | |
640 | if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) | ||
641 | return; | ||
642 | |||
643 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | ||
644 | idx = queue->index[Q_INDEX]; | ||
645 | 569 | ||
646 | if (queue_idx == QID_MGMT) | 570 | if (queue->qid == QID_MGMT) |
647 | qidx = 5; | 571 | qidx = 5; |
648 | else | 572 | else |
649 | qidx = queue_idx; | 573 | qidx = queue->qid; |
650 | 574 | ||
651 | rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx); | 575 | rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx); |
652 | } | 576 | } |
653 | 577 | ||
654 | static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 578 | static void rt2800pci_kill_tx_queue(struct data_queue *queue) |
655 | const enum data_queue_qid qid) | ||
656 | { | 579 | { |
580 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
657 | u32 reg; | 581 | u32 reg; |
658 | 582 | ||
659 | if (qid == QID_BEACON) { | 583 | if (queue->qid == QID_BEACON) { |
660 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); | 584 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); |
661 | return; | 585 | return; |
662 | } | 586 | } |
663 | 587 | ||
664 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | 588 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); |
665 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE)); | 589 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE)); |
666 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK)); | 590 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK)); |
667 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI)); | 591 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI)); |
668 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO)); | 592 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO)); |
669 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | 593 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); |
670 | } | 594 | } |
671 | 595 | ||
@@ -728,110 +652,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
728 | /* | 652 | /* |
729 | * Interrupt functions. | 653 | * Interrupt functions. |
730 | */ | 654 | */ |
731 | static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | ||
732 | { | ||
733 | struct data_queue *queue; | ||
734 | struct queue_entry *entry; | ||
735 | __le32 *txwi; | ||
736 | struct txdone_entry_desc txdesc; | ||
737 | u32 word; | ||
738 | u32 reg; | ||
739 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; | ||
740 | u16 mcs, real_mcs; | ||
741 | int i; | ||
742 | |||
743 | /* | ||
744 | * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO | ||
745 | * at most X times and also stop processing once the TX_STA_FIFO_VALID | ||
746 | * flag is not set anymore. | ||
747 | * | ||
748 | * The legacy drivers use X=TX_RING_SIZE but state in a comment | ||
749 | * that the TX_STA_FIFO stack has a size of 16. We stick to our | ||
750 | * tx ring size for now. | ||
751 | */ | ||
752 | for (i = 0; i < TX_ENTRIES; i++) { | ||
753 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); | ||
754 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | ||
755 | break; | ||
756 | |||
757 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
758 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
759 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
760 | |||
761 | /* | ||
762 | * Skip this entry when it contains an invalid | ||
763 | * queue identication number. | ||
764 | */ | ||
765 | if (pid <= 0 || pid > QID_RX) | ||
766 | continue; | ||
767 | |||
768 | queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); | ||
769 | if (unlikely(!queue)) | ||
770 | continue; | ||
771 | |||
772 | /* | ||
773 | * Inside each queue, we process each entry in a chronological | ||
774 | * order. We first check that the queue is not empty. | ||
775 | */ | ||
776 | if (rt2x00queue_empty(queue)) | ||
777 | continue; | ||
778 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
779 | |||
780 | /* Check if we got a match by looking at WCID/ACK/PID | ||
781 | * fields */ | ||
782 | txwi = (__le32 *) entry->skb->data; | ||
783 | |||
784 | rt2x00_desc_read(txwi, 1, &word); | ||
785 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
786 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
787 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
788 | |||
789 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) | ||
790 | WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n"); | ||
791 | |||
792 | /* | ||
793 | * Obtain the status about this packet. | ||
794 | */ | ||
795 | txdesc.flags = 0; | ||
796 | rt2x00_desc_read(txwi, 0, &word); | ||
797 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | ||
798 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | ||
799 | |||
800 | /* | ||
801 | * Ralink has a retry mechanism using a global fallback | ||
802 | * table. We setup this fallback table to try the immediate | ||
803 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field | ||
804 | * always contains the MCS used for the last transmission, be | ||
805 | * it successful or not. | ||
806 | */ | ||
807 | if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { | ||
808 | /* | ||
809 | * Transmission succeeded. The number of retries is | ||
810 | * mcs - real_mcs | ||
811 | */ | ||
812 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
813 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
814 | } else { | ||
815 | /* | ||
816 | * Transmission failed. The number of retries is | ||
817 | * always 7 in this case (for a total number of 8 | ||
818 | * frames sent). | ||
819 | */ | ||
820 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
821 | txdesc.retry = 7; | ||
822 | } | ||
823 | |||
824 | /* | ||
825 | * the frame was retried at least once | ||
826 | * -> hw used fallback rates | ||
827 | */ | ||
828 | if (txdesc.retry) | ||
829 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
830 | |||
831 | rt2x00lib_txdone(entry, &txdesc); | ||
832 | } | ||
833 | } | ||
834 | |||
835 | static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) | 655 | static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) |
836 | { | 656 | { |
837 | struct ieee80211_conf conf = { .flags = 0 }; | 657 | struct ieee80211_conf conf = { .flags = 0 }; |
@@ -867,7 +687,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) | |||
867 | * 4 - Tx done interrupt. | 687 | * 4 - Tx done interrupt. |
868 | */ | 688 | */ |
869 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) | 689 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) |
870 | rt2800pci_txdone(rt2x00dev); | 690 | rt2800_txdone(rt2x00dev); |
871 | 691 | ||
872 | /* | 692 | /* |
873 | * 5 - Auto wakeup interrupt. | 693 | * 5 - Auto wakeup interrupt. |
@@ -1011,6 +831,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { | |||
1011 | .regbusy_read = rt2x00pci_regbusy_read, | 831 | .regbusy_read = rt2x00pci_regbusy_read, |
1012 | .drv_write_firmware = rt2800pci_write_firmware, | 832 | .drv_write_firmware = rt2800pci_write_firmware, |
1013 | .drv_init_registers = rt2800pci_init_registers, | 833 | .drv_init_registers = rt2800pci_init_registers, |
834 | .drv_get_txwi = rt2800pci_get_txwi, | ||
1014 | }; | 835 | }; |
1015 | 836 | ||
1016 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | 837 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { |
@@ -1030,7 +851,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
1030 | .reset_tuner = rt2800_reset_tuner, | 851 | .reset_tuner = rt2800_reset_tuner, |
1031 | .link_tuner = rt2800_link_tuner, | 852 | .link_tuner = rt2800_link_tuner, |
1032 | .write_tx_desc = rt2800pci_write_tx_desc, | 853 | .write_tx_desc = rt2800pci_write_tx_desc, |
1033 | .write_tx_data = rt2800pci_write_tx_data, | 854 | .write_tx_data = rt2800_write_tx_data, |
1034 | .write_beacon = rt2800_write_beacon, | 855 | .write_beacon = rt2800_write_beacon, |
1035 | .kick_tx_queue = rt2800pci_kick_tx_queue, | 856 | .kick_tx_queue = rt2800pci_kick_tx_queue, |
1036 | .kill_tx_queue = rt2800pci_kill_tx_queue, | 857 | .kill_tx_queue = rt2800pci_kill_tx_queue, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5a2dfe87c6b6..3dff56ec195a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | 4 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> |
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | 5 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> |
5 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | 6 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> |
@@ -100,19 +101,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
100 | msleep(10); | 101 | msleep(10); |
101 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 102 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
102 | 103 | ||
103 | /* | ||
104 | * Send signal to firmware during boot time. | ||
105 | */ | ||
106 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
107 | |||
108 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
109 | rt2x00_rt(rt2x00dev, RT3071) || | ||
110 | rt2x00_rt(rt2x00dev, RT3572)) { | ||
111 | udelay(200); | ||
112 | rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); | ||
113 | udelay(10); | ||
114 | } | ||
115 | |||
116 | return 0; | 104 | return 0; |
117 | } | 105 | } |
118 | 106 | ||
@@ -134,26 +122,18 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
134 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | 122 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) |
135 | { | 123 | { |
136 | u32 reg; | 124 | u32 reg; |
137 | int i; | ||
138 | 125 | ||
139 | /* | 126 | /* |
140 | * Wait until BBP and RF are ready. | 127 | * Wait until BBP and RF are ready. |
141 | */ | 128 | */ |
142 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 129 | if (rt2800_wait_csr_ready(rt2x00dev)) |
143 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
144 | if (reg && reg != ~0) | ||
145 | break; | ||
146 | msleep(1); | ||
147 | } | ||
148 | |||
149 | if (i == REGISTER_BUSY_COUNT) { | ||
150 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
151 | return -EBUSY; | 130 | return -EBUSY; |
152 | } | ||
153 | 131 | ||
154 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | 132 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); |
155 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); | 133 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); |
156 | 134 | ||
135 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | ||
136 | |||
157 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 137 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
158 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | 138 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); |
159 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | 139 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); |
@@ -172,30 +152,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
172 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | 152 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) |
173 | { | 153 | { |
174 | u32 reg; | 154 | u32 reg; |
175 | u16 word; | ||
176 | 155 | ||
177 | /* | 156 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) |
178 | * Initialize all registers. | ||
179 | */ | ||
180 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | ||
181 | rt2800_init_registers(rt2x00dev) || | ||
182 | rt2800_init_bbp(rt2x00dev) || | ||
183 | rt2800_init_rfcsr(rt2x00dev))) | ||
184 | return -EIO; | 157 | return -EIO; |
185 | 158 | ||
186 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
187 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
188 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
189 | |||
190 | udelay(50); | ||
191 | |||
192 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
193 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
194 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
195 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
196 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
197 | |||
198 | |||
199 | rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); | 159 | rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); |
200 | rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); | 160 | rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); |
201 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); | 161 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); |
@@ -210,45 +170,12 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
210 | rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); | 170 | rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); |
211 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); | 171 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); |
212 | 172 | ||
213 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 173 | return rt2800_enable_radio(rt2x00dev); |
214 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
215 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
216 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
217 | |||
218 | /* | ||
219 | * Initialize LED control | ||
220 | */ | ||
221 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
222 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
223 | word & 0xff, (word >> 8) & 0xff); | ||
224 | |||
225 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
226 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
227 | word & 0xff, (word >> 8) & 0xff); | ||
228 | |||
229 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
230 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
231 | word & 0xff, (word >> 8) & 0xff); | ||
232 | |||
233 | return 0; | ||
234 | } | 174 | } |
235 | 175 | ||
236 | static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 176 | static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
237 | { | 177 | { |
238 | u32 reg; | 178 | rt2800_disable_radio(rt2x00dev); |
239 | |||
240 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
241 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
242 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
243 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
244 | |||
245 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); | ||
246 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
247 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
248 | |||
249 | /* Wait for DMA, ignore error */ | ||
250 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
251 | |||
252 | rt2x00usb_disable_radio(rt2x00dev); | 179 | rt2x00usb_disable_radio(rt2x00dev); |
253 | } | 180 | } |
254 | 181 | ||
@@ -320,21 +247,19 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
320 | /* | 247 | /* |
321 | * TX descriptor initialization | 248 | * TX descriptor initialization |
322 | */ | 249 | */ |
323 | static void rt2800usb_write_tx_data(struct queue_entry* entry, | 250 | static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) |
324 | struct txentry_desc *txdesc) | ||
325 | { | 251 | { |
326 | __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); | 252 | if (entry->queue->qid == QID_BEACON) |
327 | 253 | return (__le32 *) (entry->skb->data); | |
328 | rt2800_write_txwi(txwi, txdesc); | 254 | else |
255 | return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); | ||
329 | } | 256 | } |
330 | 257 | ||
331 | 258 | static void rt2800usb_write_tx_desc(struct queue_entry *entry, | |
332 | static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
333 | struct sk_buff *skb, | ||
334 | struct txentry_desc *txdesc) | 259 | struct txentry_desc *txdesc) |
335 | { | 260 | { |
336 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 261 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
337 | __le32 *txi = (__le32 *) skb->data; | 262 | __le32 *txi = (__le32 *) entry->skb->data; |
338 | u32 word; | 263 | u32 word; |
339 | 264 | ||
340 | /* | 265 | /* |
@@ -342,7 +267,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
342 | */ | 267 | */ |
343 | rt2x00_desc_read(txi, 0, &word); | 268 | rt2x00_desc_read(txi, 0, &word); |
344 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, | 269 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, |
345 | skb->len - TXINFO_DESC_SIZE); | 270 | entry->skb->len - TXINFO_DESC_SIZE); |
346 | rt2x00_set_field32(&word, TXINFO_W0_WIV, | 271 | rt2x00_set_field32(&word, TXINFO_W0_WIV, |
347 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); | 272 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); |
348 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); | 273 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); |
@@ -379,6 +304,46 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | |||
379 | } | 304 | } |
380 | 305 | ||
381 | /* | 306 | /* |
307 | * TX control handlers | ||
308 | */ | ||
309 | static void rt2800usb_work_txdone(struct work_struct *work) | ||
310 | { | ||
311 | struct rt2x00_dev *rt2x00dev = | ||
312 | container_of(work, struct rt2x00_dev, txdone_work); | ||
313 | struct data_queue *queue; | ||
314 | struct queue_entry *entry; | ||
315 | |||
316 | rt2800_txdone(rt2x00dev); | ||
317 | |||
318 | /* | ||
319 | * Process any trailing TX status reports for IO failures, | ||
320 | * we loop until we find the first non-IO error entry. This | ||
321 | * can either be a frame which is free, is being uploaded, | ||
322 | * or has completed the upload but didn't have an entry | ||
323 | * in the TX_STAT_FIFO register yet. | ||
324 | */ | ||
325 | tx_queue_for_each(rt2x00dev, queue) { | ||
326 | while (!rt2x00queue_empty(queue)) { | ||
327 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
328 | |||
329 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | ||
330 | !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | ||
331 | break; | ||
332 | |||
333 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
334 | } | ||
335 | } | ||
336 | } | ||
337 | |||
338 | static void rt2800usb_kill_tx_queue(struct data_queue *queue) | ||
339 | { | ||
340 | if (queue->qid == QID_BEACON) | ||
341 | rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0); | ||
342 | |||
343 | rt2x00usb_kill_tx_queue(queue); | ||
344 | } | ||
345 | |||
346 | /* | ||
382 | * RX control handlers | 347 | * RX control handlers |
383 | */ | 348 | */ |
384 | static void rt2800usb_fill_rxdone(struct queue_entry *entry, | 349 | static void rt2800usb_fill_rxdone(struct queue_entry *entry, |
@@ -514,6 +479,11 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
514 | */ | 479 | */ |
515 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | 480 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; |
516 | 481 | ||
482 | /* | ||
483 | * Overwrite TX done handler | ||
484 | */ | ||
485 | PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone); | ||
486 | |||
517 | return 0; | 487 | return 0; |
518 | } | 488 | } |
519 | 489 | ||
@@ -549,6 +519,7 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = { | |||
549 | .regbusy_read = rt2x00usb_regbusy_read, | 519 | .regbusy_read = rt2x00usb_regbusy_read, |
550 | .drv_write_firmware = rt2800usb_write_firmware, | 520 | .drv_write_firmware = rt2800usb_write_firmware, |
551 | .drv_init_registers = rt2800usb_init_registers, | 521 | .drv_init_registers = rt2800usb_init_registers, |
522 | .drv_get_txwi = rt2800usb_get_txwi, | ||
552 | }; | 523 | }; |
553 | 524 | ||
554 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | 525 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { |
@@ -566,11 +537,11 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
566 | .link_tuner = rt2800_link_tuner, | 537 | .link_tuner = rt2800_link_tuner, |
567 | .watchdog = rt2x00usb_watchdog, | 538 | .watchdog = rt2x00usb_watchdog, |
568 | .write_tx_desc = rt2800usb_write_tx_desc, | 539 | .write_tx_desc = rt2800usb_write_tx_desc, |
569 | .write_tx_data = rt2800usb_write_tx_data, | 540 | .write_tx_data = rt2800_write_tx_data, |
570 | .write_beacon = rt2800_write_beacon, | 541 | .write_beacon = rt2800_write_beacon, |
571 | .get_tx_data_len = rt2800usb_get_tx_data_len, | 542 | .get_tx_data_len = rt2800usb_get_tx_data_len, |
572 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 543 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
573 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 544 | .kill_tx_queue = rt2800usb_kill_tx_queue, |
574 | .fill_rxdone = rt2800usb_fill_rxdone, | 545 | .fill_rxdone = rt2800usb_fill_rxdone, |
575 | .config_shared_key = rt2800_config_shared_key, | 546 | .config_shared_key = rt2800_config_shared_key, |
576 | .config_pairwise_key = rt2800_config_pairwise_key, | 547 | .config_pairwise_key = rt2800_config_pairwise_key, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c21af38cc5af..7832a5996a8c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> | 4 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> |
4 | <http://rt2x00.serialmonkey.com> | 5 | <http://rt2x00.serialmonkey.com> |
5 | 6 | ||
@@ -212,8 +213,9 @@ struct channel_info { | |||
212 | unsigned int flags; | 213 | unsigned int flags; |
213 | #define GEOGRAPHY_ALLOWED 0x00000001 | 214 | #define GEOGRAPHY_ALLOWED 0x00000001 |
214 | 215 | ||
215 | short tx_power1; | 216 | short max_power; |
216 | short tx_power2; | 217 | short default_power1; |
218 | short default_power2; | ||
217 | }; | 219 | }; |
218 | 220 | ||
219 | /* | 221 | /* |
@@ -558,18 +560,15 @@ struct rt2x00lib_ops { | |||
558 | /* | 560 | /* |
559 | * TX control handlers | 561 | * TX control handlers |
560 | */ | 562 | */ |
561 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 563 | void (*write_tx_desc) (struct queue_entry *entry, |
562 | struct sk_buff *skb, | ||
563 | struct txentry_desc *txdesc); | 564 | struct txentry_desc *txdesc); |
564 | void (*write_tx_data) (struct queue_entry *entry, | 565 | void (*write_tx_data) (struct queue_entry *entry, |
565 | struct txentry_desc *txdesc); | 566 | struct txentry_desc *txdesc); |
566 | void (*write_beacon) (struct queue_entry *entry, | 567 | void (*write_beacon) (struct queue_entry *entry, |
567 | struct txentry_desc *txdesc); | 568 | struct txentry_desc *txdesc); |
568 | int (*get_tx_data_len) (struct queue_entry *entry); | 569 | int (*get_tx_data_len) (struct queue_entry *entry); |
569 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 570 | void (*kick_tx_queue) (struct data_queue *queue); |
570 | const enum data_queue_qid queue); | 571 | void (*kill_tx_queue) (struct data_queue *queue); |
571 | void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev, | ||
572 | const enum data_queue_qid queue); | ||
573 | 572 | ||
574 | /* | 573 | /* |
575 | * RX control handlers | 574 | * RX control handlers |
@@ -597,7 +596,8 @@ struct rt2x00lib_ops { | |||
597 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) | 596 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) |
598 | 597 | ||
599 | void (*config_erp) (struct rt2x00_dev *rt2x00dev, | 598 | void (*config_erp) (struct rt2x00_dev *rt2x00dev, |
600 | struct rt2x00lib_erp *erp); | 599 | struct rt2x00lib_erp *erp, |
600 | u32 changed); | ||
601 | void (*config_ant) (struct rt2x00_dev *rt2x00dev, | 601 | void (*config_ant) (struct rt2x00_dev *rt2x00dev, |
602 | struct antenna_setup *ant); | 602 | struct antenna_setup *ant); |
603 | void (*config) (struct rt2x00_dev *rt2x00dev, | 603 | void (*config) (struct rt2x00_dev *rt2x00dev, |
@@ -698,6 +698,7 @@ struct rt2x00_dev { | |||
698 | struct ieee80211_hw *hw; | 698 | struct ieee80211_hw *hw; |
699 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 699 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
700 | enum ieee80211_band curr_band; | 700 | enum ieee80211_band curr_band; |
701 | int curr_freq; | ||
701 | 702 | ||
702 | /* | 703 | /* |
703 | * If enabled, the debugfs interface structures | 704 | * If enabled, the debugfs interface structures |
@@ -850,11 +851,6 @@ struct rt2x00_dev { | |||
850 | struct ieee80211_low_level_stats low_level_stats; | 851 | struct ieee80211_low_level_stats low_level_stats; |
851 | 852 | ||
852 | /* | 853 | /* |
853 | * RX configuration information. | ||
854 | */ | ||
855 | struct ieee80211_rx_status rx_status; | ||
856 | |||
857 | /* | ||
858 | * Scheduled work. | 854 | * Scheduled work. |
859 | * NOTE: intf_work will use ieee80211_iterate_active_interfaces() | 855 | * NOTE: intf_work will use ieee80211_iterate_active_interfaces() |
860 | * which means it cannot be placed on the hw->workqueue | 856 | * which means it cannot be placed on the hw->workqueue |
@@ -862,6 +858,12 @@ struct rt2x00_dev { | |||
862 | */ | 858 | */ |
863 | struct work_struct intf_work; | 859 | struct work_struct intf_work; |
864 | 860 | ||
861 | /** | ||
862 | * Scheduled work for TX/RX done handling (USB devices) | ||
863 | */ | ||
864 | struct work_struct rxdone_work; | ||
865 | struct work_struct txdone_work; | ||
866 | |||
865 | /* | 867 | /* |
866 | * Data queue arrays for RX, TX and Beacon. | 868 | * Data queue arrays for RX, TX and Beacon. |
867 | * The Beacon array also contains the Atim queue | 869 | * The Beacon array also contains the Atim queue |
@@ -1069,8 +1071,10 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
1069 | */ | 1071 | */ |
1070 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 1072 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
1071 | void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); | 1073 | void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); |
1074 | void rt2x00lib_dmadone(struct queue_entry *entry); | ||
1072 | void rt2x00lib_txdone(struct queue_entry *entry, | 1075 | void rt2x00lib_txdone(struct queue_entry *entry, |
1073 | struct txdone_entry_desc *txdesc); | 1076 | struct txdone_entry_desc *txdesc); |
1077 | void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); | ||
1074 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | 1078 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, |
1075 | struct queue_entry *entry); | 1079 | struct queue_entry *entry); |
1076 | 1080 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 953dc4f2c6af..4c7ff765a8bf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -81,7 +81,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |||
81 | 81 | ||
82 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | 82 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, |
83 | struct rt2x00_intf *intf, | 83 | struct rt2x00_intf *intf, |
84 | struct ieee80211_bss_conf *bss_conf) | 84 | struct ieee80211_bss_conf *bss_conf, |
85 | u32 changed) | ||
85 | { | 86 | { |
86 | struct rt2x00lib_erp erp; | 87 | struct rt2x00lib_erp erp; |
87 | 88 | ||
@@ -102,7 +103,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
102 | /* Update global beacon interval time, this is needed for PS support */ | 103 | /* Update global beacon interval time, this is needed for PS support */ |
103 | rt2x00dev->beacon_int = bss_conf->beacon_int; | 104 | rt2x00dev->beacon_int = bss_conf->beacon_int; |
104 | 105 | ||
105 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); | 106 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); |
106 | } | 107 | } |
107 | 108 | ||
108 | static inline | 109 | static inline |
@@ -126,25 +127,17 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
126 | * ANTENNA_SW_DIVERSITY state to the driver. | 127 | * ANTENNA_SW_DIVERSITY state to the driver. |
127 | * If that happens, fallback to hardware defaults, | 128 | * If that happens, fallback to hardware defaults, |
128 | * or our own default. | 129 | * or our own default. |
129 | * If diversity handling is active for a particular antenna, | ||
130 | * we shouldn't overwrite that antenna. | ||
131 | * The calls to rt2x00lib_config_antenna_check() | ||
132 | * might have caused that we restore back to the already | ||
133 | * active setting. If that has happened we can quit. | ||
134 | */ | 130 | */ |
135 | if (!(ant->flags & ANTENNA_RX_DIVERSITY)) | 131 | if (!(ant->flags & ANTENNA_RX_DIVERSITY)) |
136 | config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); | 132 | config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); |
137 | else | 133 | else if(config.rx == ANTENNA_SW_DIVERSITY) |
138 | config.rx = active->rx; | 134 | config.rx = active->rx; |
139 | 135 | ||
140 | if (!(ant->flags & ANTENNA_TX_DIVERSITY)) | 136 | if (!(ant->flags & ANTENNA_TX_DIVERSITY)) |
141 | config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); | 137 | config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); |
142 | else | 138 | else if (config.tx == ANTENNA_SW_DIVERSITY) |
143 | config.tx = active->tx; | 139 | config.tx = active->tx; |
144 | 140 | ||
145 | if (config.rx == active->rx && config.tx == active->tx) | ||
146 | return; | ||
147 | |||
148 | /* | 141 | /* |
149 | * Antenna setup changes require the RX to be disabled, | 142 | * Antenna setup changes require the RX to be disabled, |
150 | * else the changes will be ignored by the device. | 143 | * else the changes will be ignored by the device. |
@@ -209,10 +202,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
209 | rt2x00link_reset_tuner(rt2x00dev, false); | 202 | rt2x00link_reset_tuner(rt2x00dev, false); |
210 | 203 | ||
211 | rt2x00dev->curr_band = conf->channel->band; | 204 | rt2x00dev->curr_band = conf->channel->band; |
205 | rt2x00dev->curr_freq = conf->channel->center_freq; | ||
212 | rt2x00dev->tx_power = conf->power_level; | 206 | rt2x00dev->tx_power = conf->power_level; |
213 | rt2x00dev->short_retry = conf->short_frame_max_tx_count; | 207 | rt2x00dev->short_retry = conf->short_frame_max_tx_count; |
214 | rt2x00dev->long_retry = conf->long_frame_max_tx_count; | 208 | rt2x00dev->long_retry = conf->long_frame_max_tx_count; |
215 | |||
216 | rt2x00dev->rx_status.band = conf->channel->band; | ||
217 | rt2x00dev->rx_status.freq = conf->channel->center_freq; | ||
218 | } | 209 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 583dacd8d241..5e9074bf2b8e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -31,15 +31,14 @@ | |||
31 | 31 | ||
32 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) | 32 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) |
33 | { | 33 | { |
34 | switch (key->alg) { | 34 | switch (key->cipher) { |
35 | case ALG_WEP: | 35 | case WLAN_CIPHER_SUITE_WEP40: |
36 | if (key->keylen == WLAN_KEY_LEN_WEP40) | 36 | return CIPHER_WEP64; |
37 | return CIPHER_WEP64; | 37 | case WLAN_CIPHER_SUITE_WEP104: |
38 | else | 38 | return CIPHER_WEP128; |
39 | return CIPHER_WEP128; | 39 | case WLAN_CIPHER_SUITE_TKIP: |
40 | case ALG_TKIP: | ||
41 | return CIPHER_TKIP; | 40 | return CIPHER_TKIP; |
42 | case ALG_CCMP: | 41 | case WLAN_CIPHER_SUITE_CCMP: |
43 | return CIPHER_AES; | 42 | return CIPHER_AES; |
44 | default: | 43 | default: |
45 | return CIPHER_NONE; | 44 | return CIPHER_NONE; |
@@ -95,7 +94,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, | |||
95 | overhead += key->iv_len; | 94 | overhead += key->iv_len; |
96 | 95 | ||
97 | if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { | 96 | if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { |
98 | if (key->alg == ALG_TKIP) | 97 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) |
99 | overhead += 8; | 98 | overhead += 8; |
100 | } | 99 | } |
101 | 100 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b0498e7e7aae..c1710b27ba70 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -333,12 +333,12 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, | |||
333 | if (*offset) | 333 | if (*offset) |
334 | return 0; | 334 | return 0; |
335 | 335 | ||
336 | data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); | 336 | data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL); |
337 | if (!data) | 337 | if (!data) |
338 | return -ENOMEM; | 338 | return -ENOMEM; |
339 | 339 | ||
340 | temp = data + | 340 | temp = data + |
341 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | 341 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); |
342 | 342 | ||
343 | queue_for_each(intf->rt2x00dev, queue) { | 343 | queue_for_each(intf->rt2x00dev, queue) { |
344 | spin_lock_irqsave(&queue->lock, irqflags); | 344 | spin_lock_irqsave(&queue->lock, irqflags); |
@@ -346,8 +346,8 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, | |||
346 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | 346 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, |
347 | queue->count, queue->limit, queue->length, | 347 | queue->count, queue->limit, queue->length, |
348 | queue->index[Q_INDEX], | 348 | queue->index[Q_INDEX], |
349 | queue->index[Q_INDEX_DONE], | 349 | queue->index[Q_INDEX_DMA_DONE], |
350 | queue->index[Q_INDEX_CRYPTO]); | 350 | queue->index[Q_INDEX_DONE]); |
351 | 351 | ||
352 | spin_unlock_irqrestore(&queue->lock, irqflags); | 352 | spin_unlock_irqrestore(&queue->lock, irqflags); |
353 | } | 353 | } |
@@ -380,7 +380,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file, | |||
380 | loff_t *offset) | 380 | loff_t *offset) |
381 | { | 381 | { |
382 | struct rt2x00debug_intf *intf = file->private_data; | 382 | struct rt2x00debug_intf *intf = file->private_data; |
383 | char *name[] = { "WEP64", "WEP128", "TKIP", "AES" }; | 383 | static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" }; |
384 | char *data; | 384 | char *data; |
385 | char *temp; | 385 | char *temp; |
386 | size_t size; | 386 | size_t size; |
@@ -481,6 +481,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \ | |||
481 | if (index >= debug->__name.word_count) \ | 481 | if (index >= debug->__name.word_count) \ |
482 | return -EINVAL; \ | 482 | return -EINVAL; \ |
483 | \ | 483 | \ |
484 | if (length > sizeof(line)) \ | ||
485 | return -EINVAL; \ | ||
486 | \ | ||
484 | if (copy_from_user(line, buf, length)) \ | 487 | if (copy_from_user(line, buf, length)) \ |
485 | return -EFAULT; \ | 488 | return -EFAULT; \ |
486 | \ | 489 | \ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 585e8166f22a..053fdd3bd720 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -250,6 +251,12 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) | |||
250 | } | 251 | } |
251 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); | 252 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); |
252 | 253 | ||
254 | void rt2x00lib_dmadone(struct queue_entry *entry) | ||
255 | { | ||
256 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); | ||
259 | |||
253 | void rt2x00lib_txdone(struct queue_entry *entry, | 260 | void rt2x00lib_txdone(struct queue_entry *entry, |
254 | struct txdone_entry_desc *txdesc) | 261 | struct txdone_entry_desc *txdesc) |
255 | { | 262 | { |
@@ -383,15 +390,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
383 | * send the status report back. | 390 | * send the status report back. |
384 | */ | 391 | */ |
385 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) | 392 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) |
386 | /* | 393 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); |
387 | * Only PCI and SOC devices process the tx status in process | ||
388 | * context. Hence use ieee80211_tx_status for PCI and SOC | ||
389 | * devices and stick to ieee80211_tx_status_irqsafe for USB. | ||
390 | */ | ||
391 | if (rt2x00_is_usb(rt2x00dev)) | ||
392 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); | ||
393 | else | ||
394 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); | ||
395 | else | 394 | else |
396 | dev_kfree_skb_any(entry->skb); | 395 | dev_kfree_skb_any(entry->skb); |
397 | 396 | ||
@@ -403,7 +402,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
403 | 402 | ||
404 | rt2x00dev->ops->lib->clear_entry(entry); | 403 | rt2x00dev->ops->lib->clear_entry(entry); |
405 | 404 | ||
406 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
407 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 405 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
408 | 406 | ||
409 | /* | 407 | /* |
@@ -416,6 +414,18 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
416 | } | 414 | } |
417 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 415 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
418 | 416 | ||
417 | void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status) | ||
418 | { | ||
419 | struct txdone_entry_desc txdesc; | ||
420 | |||
421 | txdesc.flags = 0; | ||
422 | __set_bit(status, &txdesc.flags); | ||
423 | txdesc.retry = 0; | ||
424 | |||
425 | rt2x00lib_txdone(entry, &txdesc); | ||
426 | } | ||
427 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); | ||
428 | |||
419 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, | 429 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, |
420 | struct rxdone_entry_desc *rxdesc) | 430 | struct rxdone_entry_desc *rxdesc) |
421 | { | 431 | { |
@@ -460,9 +470,13 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
460 | { | 470 | { |
461 | struct rxdone_entry_desc rxdesc; | 471 | struct rxdone_entry_desc rxdesc; |
462 | struct sk_buff *skb; | 472 | struct sk_buff *skb; |
463 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 473 | struct ieee80211_rx_status *rx_status; |
464 | unsigned int header_length; | 474 | unsigned int header_length; |
465 | int rate_idx; | 475 | int rate_idx; |
476 | |||
477 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | ||
478 | goto submit_entry; | ||
479 | |||
466 | /* | 480 | /* |
467 | * Allocate a new sk_buffer. If no new buffer available, drop the | 481 | * Allocate a new sk_buffer. If no new buffer available, drop the |
468 | * received frame and reuse the existing buffer. | 482 | * received frame and reuse the existing buffer. |
@@ -527,39 +541,32 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
527 | */ | 541 | */ |
528 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); | 542 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); |
529 | rt2x00debug_update_crypto(rt2x00dev, &rxdesc); | 543 | rt2x00debug_update_crypto(rt2x00dev, &rxdesc); |
544 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); | ||
530 | 545 | ||
546 | /* | ||
547 | * Initialize RX status information, and send frame | ||
548 | * to mac80211. | ||
549 | */ | ||
550 | rx_status = IEEE80211_SKB_RXCB(entry->skb); | ||
531 | rx_status->mactime = rxdesc.timestamp; | 551 | rx_status->mactime = rxdesc.timestamp; |
552 | rx_status->band = rt2x00dev->curr_band; | ||
553 | rx_status->freq = rt2x00dev->curr_freq; | ||
532 | rx_status->rate_idx = rate_idx; | 554 | rx_status->rate_idx = rate_idx; |
533 | rx_status->signal = rxdesc.rssi; | 555 | rx_status->signal = rxdesc.rssi; |
534 | rx_status->flag = rxdesc.flags; | 556 | rx_status->flag = rxdesc.flags; |
535 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 557 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
536 | 558 | ||
537 | /* | 559 | ieee80211_rx_ni(rt2x00dev->hw, entry->skb); |
538 | * Send frame to mac80211 & debugfs. | ||
539 | * mac80211 will clean up the skb structure. | ||
540 | */ | ||
541 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); | ||
542 | memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); | ||
543 | |||
544 | /* | ||
545 | * Currently only PCI and SOC devices handle rx interrupts in process | ||
546 | * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni | ||
547 | * for PCI and SOC devices. | ||
548 | */ | ||
549 | if (rt2x00_is_usb(rt2x00dev)) | ||
550 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); | ||
551 | else | ||
552 | ieee80211_rx_ni(rt2x00dev->hw, entry->skb); | ||
553 | 560 | ||
554 | /* | 561 | /* |
555 | * Replace the skb with the freshly allocated one. | 562 | * Replace the skb with the freshly allocated one. |
556 | */ | 563 | */ |
557 | entry->skb = skb; | 564 | entry->skb = skb; |
558 | entry->flags = 0; | ||
559 | 565 | ||
566 | submit_entry: | ||
560 | rt2x00dev->ops->lib->clear_entry(entry); | 567 | rt2x00dev->ops->lib->clear_entry(entry); |
561 | |||
562 | rt2x00queue_index_inc(entry->queue, Q_INDEX); | 568 | rt2x00queue_index_inc(entry->queue, Q_INDEX); |
569 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | ||
563 | } | 570 | } |
564 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 571 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
565 | 572 | ||
@@ -710,7 +717,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
710 | for (i = 0; i < spec->num_channels; i++) { | 717 | for (i = 0; i < spec->num_channels; i++) { |
711 | rt2x00lib_channel(&channels[i], | 718 | rt2x00lib_channel(&channels[i], |
712 | spec->channels[i].channel, | 719 | spec->channels[i].channel, |
713 | spec->channels_info[i].tx_power1, i); | 720 | spec->channels_info[i].max_power, i); |
714 | } | 721 | } |
715 | 722 | ||
716 | /* | 723 | /* |
@@ -1017,6 +1024,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1017 | * Stop all work. | 1024 | * Stop all work. |
1018 | */ | 1025 | */ |
1019 | cancel_work_sync(&rt2x00dev->intf_work); | 1026 | cancel_work_sync(&rt2x00dev->intf_work); |
1027 | cancel_work_sync(&rt2x00dev->rxdone_work); | ||
1028 | cancel_work_sync(&rt2x00dev->txdone_work); | ||
1020 | 1029 | ||
1021 | /* | 1030 | /* |
1022 | * Uninitialize device. | 1031 | * Uninitialize device. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index b818a43c4672..f0e1eb72befc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -63,6 +63,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
63 | 63 | ||
64 | INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", | 64 | INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", |
65 | fw->data[fw->size - 4], fw->data[fw->size - 3]); | 65 | fw->data[fw->size - 4], fw->data[fw->size - 3]); |
66 | snprintf(rt2x00dev->hw->wiphy->fw_version, | ||
67 | sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", | ||
68 | fw->data[fw->size - 4], fw->data[fw->size - 3]); | ||
66 | 69 | ||
67 | retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size); | 70 | retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size); |
68 | switch (retval) { | 71 | switch (retval) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index c004cd3a8847..ad3c7ff4837b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c | |||
@@ -54,6 +54,16 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
54 | */ | 54 | */ |
55 | if (txrate->flags & IEEE80211_TX_RC_MCS) { | 55 | if (txrate->flags & IEEE80211_TX_RC_MCS) { |
56 | txdesc->mcs = txrate->idx; | 56 | txdesc->mcs = txrate->idx; |
57 | |||
58 | /* | ||
59 | * MIMO PS should be set to 1 for STA's using dynamic SM PS | ||
60 | * when using more then one tx stream (>MCS7). | ||
61 | */ | ||
62 | if (tx_info->control.sta && txdesc->mcs > 7 && | ||
63 | (tx_info->control.sta->ht_cap.cap & | ||
64 | (WLAN_HT_CAP_SM_PS_DYNAMIC << | ||
65 | IEEE80211_HT_CAP_SM_PS_SHIFT))) | ||
66 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); | ||
57 | } else { | 67 | } else { |
58 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); | 68 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); |
59 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | 69 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index dc5c6574aaf4..70c85ac2e53e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -86,7 +86,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |||
86 | const u8 *mac, const u8 *bssid); | 86 | const u8 *mac, const u8 *bssid); |
87 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | 87 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, |
88 | struct rt2x00_intf *intf, | 88 | struct rt2x00_intf *intf, |
89 | struct ieee80211_bss_conf *conf); | 89 | struct ieee80211_bss_conf *conf, |
90 | u32 changed); | ||
90 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 91 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
91 | struct antenna_setup ant); | 92 | struct antenna_setup ant); |
92 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 93 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 666cef3f8472..4d534e9dc628 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -188,7 +188,6 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev) | |||
188 | static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | 188 | static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) |
189 | { | 189 | { |
190 | struct link_ant *ant = &rt2x00dev->link.ant; | 190 | struct link_ant *ant = &rt2x00dev->link.ant; |
191 | unsigned int flags = ant->flags; | ||
192 | 191 | ||
193 | /* | 192 | /* |
194 | * Determine if software diversity is enabled for | 193 | * Determine if software diversity is enabled for |
@@ -196,13 +195,13 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | |||
196 | * Always perform this check since within the link | 195 | * Always perform this check since within the link |
197 | * tuner interval the configuration might have changed. | 196 | * tuner interval the configuration might have changed. |
198 | */ | 197 | */ |
199 | flags &= ~ANTENNA_RX_DIVERSITY; | 198 | ant->flags &= ~ANTENNA_RX_DIVERSITY; |
200 | flags &= ~ANTENNA_TX_DIVERSITY; | 199 | ant->flags &= ~ANTENNA_TX_DIVERSITY; |
201 | 200 | ||
202 | if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) | 201 | if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) |
203 | flags |= ANTENNA_RX_DIVERSITY; | 202 | ant->flags |= ANTENNA_RX_DIVERSITY; |
204 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) | 203 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) |
205 | flags |= ANTENNA_TX_DIVERSITY; | 204 | ant->flags |= ANTENNA_TX_DIVERSITY; |
206 | 205 | ||
207 | if (!(ant->flags & ANTENNA_RX_DIVERSITY) && | 206 | if (!(ant->flags & ANTENNA_RX_DIVERSITY) && |
208 | !(ant->flags & ANTENNA_TX_DIVERSITY)) { | 207 | !(ant->flags & ANTENNA_TX_DIVERSITY)) { |
@@ -210,9 +209,6 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | |||
210 | return true; | 209 | return true; |
211 | } | 210 | } |
212 | 211 | ||
213 | /* Update flags */ | ||
214 | ant->flags = flags; | ||
215 | |||
216 | /* | 212 | /* |
217 | * If we have only sampled the data over the last period | 213 | * If we have only sampled the data over the last period |
218 | * we should now harvest the data. Otherwise just evaluate | 214 | * we should now harvest the data. Otherwise just evaluate |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 235e037e6509..7862a840984a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -669,8 +669,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
669 | * When the erp information has changed, we should perform | 669 | * When the erp information has changed, we should perform |
670 | * additional configuration steps. For all other changes we are done. | 670 | * additional configuration steps. For all other changes we are done. |
671 | */ | 671 | */ |
672 | if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) | 672 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | |
673 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); | 673 | BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | |
674 | BSS_CHANGED_BEACON_INT)) | ||
675 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); | ||
674 | } | 676 | } |
675 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 677 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
676 | 678 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a3401d301058..eede99939db9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> | 4 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> |
4 | <http://rt2x00.serialmonkey.com> | 5 | <http://rt2x00.serialmonkey.com> |
5 | 6 | ||
@@ -311,7 +312,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
311 | /* | 312 | /* |
312 | * Initialize information from queue | 313 | * Initialize information from queue |
313 | */ | 314 | */ |
314 | txdesc->queue = entry->queue->qid; | 315 | txdesc->qid = entry->queue->qid; |
315 | txdesc->cw_min = entry->queue->cw_min; | 316 | txdesc->cw_min = entry->queue->cw_min; |
316 | txdesc->cw_max = entry->queue->cw_max; | 317 | txdesc->cw_max = entry->queue->cw_max; |
317 | txdesc->aifs = entry->queue->aifs; | 318 | txdesc->aifs = entry->queue->aifs; |
@@ -448,15 +449,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
448 | struct txentry_desc *txdesc) | 449 | struct txentry_desc *txdesc) |
449 | { | 450 | { |
450 | struct data_queue *queue = entry->queue; | 451 | struct data_queue *queue = entry->queue; |
451 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
452 | 452 | ||
453 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | 453 | queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc); |
454 | 454 | ||
455 | /* | 455 | /* |
456 | * All processing on the frame has been completed, this means | 456 | * All processing on the frame has been completed, this means |
457 | * it is now ready to be dumped to userspace through debugfs. | 457 | * it is now ready to be dumped to userspace through debugfs. |
458 | */ | 458 | */ |
459 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); | 459 | rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); |
460 | } | 460 | } |
461 | 461 | ||
462 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | 462 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, |
@@ -476,7 +476,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | |||
476 | */ | 476 | */ |
477 | if (rt2x00queue_threshold(queue) || | 477 | if (rt2x00queue_threshold(queue) || |
478 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | 478 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) |
479 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | 479 | rt2x00dev->ops->lib->kick_tx_queue(queue); |
480 | } | 480 | } |
481 | 481 | ||
482 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | 482 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, |
@@ -590,7 +590,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
590 | intf->beacon->skb = NULL; | 590 | intf->beacon->skb = NULL; |
591 | 591 | ||
592 | if (!enable_beacon) { | 592 | if (!enable_beacon) { |
593 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON); | 593 | rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); |
594 | mutex_unlock(&intf->beacon_skb_mutex); | 594 | mutex_unlock(&intf->beacon_skb_mutex); |
595 | return 0; | 595 | return 0; |
596 | } | 596 | } |
@@ -625,6 +625,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
625 | return 0; | 625 | return 0; |
626 | } | 626 | } |
627 | 627 | ||
628 | void rt2x00queue_for_each_entry(struct data_queue *queue, | ||
629 | enum queue_index start, | ||
630 | enum queue_index end, | ||
631 | void (*fn)(struct queue_entry *entry)) | ||
632 | { | ||
633 | unsigned long irqflags; | ||
634 | unsigned int index_start; | ||
635 | unsigned int index_end; | ||
636 | unsigned int i; | ||
637 | |||
638 | if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { | ||
639 | ERROR(queue->rt2x00dev, | ||
640 | "Entry requested from invalid index range (%d - %d)\n", | ||
641 | start, end); | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * Only protect the range we are going to loop over, | ||
647 | * if during our loop a extra entry is set to pending | ||
648 | * it should not be kicked during this run, since it | ||
649 | * is part of another TX operation. | ||
650 | */ | ||
651 | spin_lock_irqsave(&queue->lock, irqflags); | ||
652 | index_start = queue->index[start]; | ||
653 | index_end = queue->index[end]; | ||
654 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
655 | |||
656 | /* | ||
657 | * Start from the TX done pointer, this guarentees that we will | ||
658 | * send out all frames in the correct order. | ||
659 | */ | ||
660 | if (index_start < index_end) { | ||
661 | for (i = index_start; i < index_end; i++) | ||
662 | fn(&queue->entries[i]); | ||
663 | } else { | ||
664 | for (i = index_start; i < queue->limit; i++) | ||
665 | fn(&queue->entries[i]); | ||
666 | |||
667 | for (i = 0; i < index_end; i++) | ||
668 | fn(&queue->entries[i]); | ||
669 | } | ||
670 | } | ||
671 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); | ||
672 | |||
628 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 673 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
629 | const enum data_queue_qid queue) | 674 | const enum data_queue_qid queue) |
630 | { | 675 | { |
@@ -686,13 +731,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
686 | if (queue->index[index] >= queue->limit) | 731 | if (queue->index[index] >= queue->limit) |
687 | queue->index[index] = 0; | 732 | queue->index[index] = 0; |
688 | 733 | ||
734 | queue->last_action[index] = jiffies; | ||
735 | |||
689 | if (index == Q_INDEX) { | 736 | if (index == Q_INDEX) { |
690 | queue->length++; | 737 | queue->length++; |
691 | queue->last_index = jiffies; | ||
692 | } else if (index == Q_INDEX_DONE) { | 738 | } else if (index == Q_INDEX_DONE) { |
693 | queue->length--; | 739 | queue->length--; |
694 | queue->count++; | 740 | queue->count++; |
695 | queue->last_index_done = jiffies; | ||
696 | } | 741 | } |
697 | 742 | ||
698 | spin_unlock_irqrestore(&queue->lock, irqflags); | 743 | spin_unlock_irqrestore(&queue->lock, irqflags); |
@@ -701,14 +746,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
701 | static void rt2x00queue_reset(struct data_queue *queue) | 746 | static void rt2x00queue_reset(struct data_queue *queue) |
702 | { | 747 | { |
703 | unsigned long irqflags; | 748 | unsigned long irqflags; |
749 | unsigned int i; | ||
704 | 750 | ||
705 | spin_lock_irqsave(&queue->lock, irqflags); | 751 | spin_lock_irqsave(&queue->lock, irqflags); |
706 | 752 | ||
707 | queue->count = 0; | 753 | queue->count = 0; |
708 | queue->length = 0; | 754 | queue->length = 0; |
709 | queue->last_index = jiffies; | 755 | |
710 | queue->last_index_done = jiffies; | 756 | for (i = 0; i < Q_INDEX_MAX; i++) { |
711 | memset(queue->index, 0, sizeof(queue->index)); | 757 | queue->index[i] = 0; |
758 | queue->last_action[i] = jiffies; | ||
759 | } | ||
712 | 760 | ||
713 | spin_unlock_irqrestore(&queue->lock, irqflags); | 761 | spin_unlock_irqrestore(&queue->lock, irqflags); |
714 | } | 762 | } |
@@ -718,7 +766,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) | |||
718 | struct data_queue *queue; | 766 | struct data_queue *queue; |
719 | 767 | ||
720 | txall_queue_for_each(rt2x00dev, queue) | 768 | txall_queue_for_each(rt2x00dev, queue) |
721 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid); | 769 | rt2x00dev->ops->lib->kill_tx_queue(queue); |
722 | } | 770 | } |
723 | 771 | ||
724 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) | 772 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) |
@@ -730,9 +778,9 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) | |||
730 | rt2x00queue_reset(queue); | 778 | rt2x00queue_reset(queue); |
731 | 779 | ||
732 | for (i = 0; i < queue->limit; i++) { | 780 | for (i = 0; i < queue->limit; i++) { |
733 | queue->entries[i].flags = 0; | ||
734 | |||
735 | rt2x00dev->ops->lib->clear_entry(&queue->entries[i]); | 781 | rt2x00dev->ops->lib->clear_entry(&queue->entries[i]); |
782 | if (queue->qid == QID_RX) | ||
783 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
736 | } | 784 | } |
737 | } | 785 | } |
738 | } | 786 | } |
@@ -755,7 +803,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
755 | * Allocate all queue entries. | 803 | * Allocate all queue entries. |
756 | */ | 804 | */ |
757 | entry_size = sizeof(*entries) + qdesc->priv_size; | 805 | entry_size = sizeof(*entries) + qdesc->priv_size; |
758 | entries = kzalloc(queue->limit * entry_size, GFP_KERNEL); | 806 | entries = kcalloc(queue->limit, entry_size, GFP_KERNEL); |
759 | if (!entries) | 807 | if (!entries) |
760 | return -ENOMEM; | 808 | return -ENOMEM; |
761 | 809 | ||
@@ -891,7 +939,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
891 | */ | 939 | */ |
892 | rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim; | 940 | rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim; |
893 | 941 | ||
894 | queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); | 942 | queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); |
895 | if (!queue) { | 943 | if (!queue) { |
896 | ERROR(rt2x00dev, "Queue allocation failed.\n"); | 944 | ERROR(rt2x00dev, "Queue allocation failed.\n"); |
897 | return -ENOMEM; | 945 | return -ENOMEM; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 191e7775a9c0..d81d85f34866 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -268,6 +268,7 @@ struct txdone_entry_desc { | |||
268 | * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU. | 268 | * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU. |
269 | * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth. | 269 | * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth. |
270 | * @ENTRY_TXD_HT_SHORT_GI: Use short GI. | 270 | * @ENTRY_TXD_HT_SHORT_GI: Use short GI. |
271 | * @ENTRY_TXD_HT_MIMO_PS: The receiving STA is in dynamic SM PS mode. | ||
271 | */ | 272 | */ |
272 | enum txentry_desc_flags { | 273 | enum txentry_desc_flags { |
273 | ENTRY_TXD_RTS_FRAME, | 274 | ENTRY_TXD_RTS_FRAME, |
@@ -286,6 +287,7 @@ enum txentry_desc_flags { | |||
286 | ENTRY_TXD_HT_AMPDU, | 287 | ENTRY_TXD_HT_AMPDU, |
287 | ENTRY_TXD_HT_BW_40, | 288 | ENTRY_TXD_HT_BW_40, |
288 | ENTRY_TXD_HT_SHORT_GI, | 289 | ENTRY_TXD_HT_SHORT_GI, |
290 | ENTRY_TXD_HT_MIMO_PS, | ||
289 | }; | 291 | }; |
290 | 292 | ||
291 | /** | 293 | /** |
@@ -294,7 +296,7 @@ enum txentry_desc_flags { | |||
294 | * Summary of information for the frame descriptor before sending a TX frame. | 296 | * Summary of information for the frame descriptor before sending a TX frame. |
295 | * | 297 | * |
296 | * @flags: Descriptor flags (See &enum queue_entry_flags). | 298 | * @flags: Descriptor flags (See &enum queue_entry_flags). |
297 | * @queue: Queue identification (See &enum data_queue_qid). | 299 | * @qid: Queue identification (See &enum data_queue_qid). |
298 | * @length: Length of the entire frame. | 300 | * @length: Length of the entire frame. |
299 | * @header_length: Length of 802.11 header. | 301 | * @header_length: Length of 802.11 header. |
300 | * @length_high: PLCP length high word. | 302 | * @length_high: PLCP length high word. |
@@ -320,7 +322,7 @@ enum txentry_desc_flags { | |||
320 | struct txentry_desc { | 322 | struct txentry_desc { |
321 | unsigned long flags; | 323 | unsigned long flags; |
322 | 324 | ||
323 | enum data_queue_qid queue; | 325 | enum data_queue_qid qid; |
324 | 326 | ||
325 | u16 length; | 327 | u16 length; |
326 | u16 header_length; | 328 | u16 header_length; |
@@ -358,17 +360,17 @@ struct txentry_desc { | |||
358 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data | 360 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data |
359 | * transfer (either TX or RX depending on the queue). The entry should | 361 | * transfer (either TX or RX depending on the queue). The entry should |
360 | * only be touched after the device has signaled it is done with it. | 362 | * only be touched after the device has signaled it is done with it. |
361 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | ||
362 | * encryption or decryption. The entry should only be touched after | ||
363 | * the device has signaled it is done with it. | ||
364 | * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting | 363 | * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting |
365 | * for the signal to start sending. | 364 | * for the signal to start sending. |
365 | * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured | ||
366 | * while transfering the data to the hardware. No TX status report will | ||
367 | * be expected from the hardware. | ||
366 | */ | 368 | */ |
367 | enum queue_entry_flags { | 369 | enum queue_entry_flags { |
368 | ENTRY_BCN_ASSIGNED, | 370 | ENTRY_BCN_ASSIGNED, |
369 | ENTRY_OWNER_DEVICE_DATA, | 371 | ENTRY_OWNER_DEVICE_DATA, |
370 | ENTRY_OWNER_DEVICE_CRYPTO, | ||
371 | ENTRY_DATA_PENDING, | 372 | ENTRY_DATA_PENDING, |
373 | ENTRY_DATA_IO_FAILED | ||
372 | }; | 374 | }; |
373 | 375 | ||
374 | /** | 376 | /** |
@@ -399,18 +401,18 @@ struct queue_entry { | |||
399 | * | 401 | * |
400 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is | 402 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is |
401 | * owned by the hardware then the queue is considered to be full. | 403 | * owned by the hardware then the queue is considered to be full. |
404 | * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been | ||
405 | * transfered to the hardware. | ||
402 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by | 406 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by |
403 | * the hardware and for which we need to run the txdone handler. If this | 407 | * the hardware and for which we need to run the txdone handler. If this |
404 | * entry is not owned by the hardware the queue is considered to be empty. | 408 | * entry is not owned by the hardware the queue is considered to be empty. |
405 | * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription | ||
406 | * will be completed by the hardware next. | ||
407 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size | 409 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size |
408 | * of the index array. | 410 | * of the index array. |
409 | */ | 411 | */ |
410 | enum queue_index { | 412 | enum queue_index { |
411 | Q_INDEX, | 413 | Q_INDEX, |
414 | Q_INDEX_DMA_DONE, | ||
412 | Q_INDEX_DONE, | 415 | Q_INDEX_DONE, |
413 | Q_INDEX_CRYPTO, | ||
414 | Q_INDEX_MAX, | 416 | Q_INDEX_MAX, |
415 | }; | 417 | }; |
416 | 418 | ||
@@ -446,13 +448,12 @@ struct data_queue { | |||
446 | enum data_queue_qid qid; | 448 | enum data_queue_qid qid; |
447 | 449 | ||
448 | spinlock_t lock; | 450 | spinlock_t lock; |
449 | unsigned long last_index; | ||
450 | unsigned long last_index_done; | ||
451 | unsigned int count; | 451 | unsigned int count; |
452 | unsigned short limit; | 452 | unsigned short limit; |
453 | unsigned short threshold; | 453 | unsigned short threshold; |
454 | unsigned short length; | 454 | unsigned short length; |
455 | unsigned short index[Q_INDEX_MAX]; | 455 | unsigned short index[Q_INDEX_MAX]; |
456 | unsigned long last_action[Q_INDEX_MAX]; | ||
456 | 457 | ||
457 | unsigned short txop; | 458 | unsigned short txop; |
458 | unsigned short aifs; | 459 | unsigned short aifs; |
@@ -565,6 +566,22 @@ struct data_queue_desc { | |||
565 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) | 566 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) |
566 | 567 | ||
567 | /** | 568 | /** |
569 | * rt2x00queue_for_each_entry - Loop through all entries in the queue | ||
570 | * @queue: Pointer to @data_queue | ||
571 | * @start: &enum queue_index Pointer to start index | ||
572 | * @end: &enum queue_index Pointer to end index | ||
573 | * @fn: The function to call for each &struct queue_entry | ||
574 | * | ||
575 | * This will walk through all entries in the queue, in chronological | ||
576 | * order. This means it will start at the current @start pointer | ||
577 | * and will walk through the queue until it reaches the @end pointer. | ||
578 | */ | ||
579 | void rt2x00queue_for_each_entry(struct data_queue *queue, | ||
580 | enum queue_index start, | ||
581 | enum queue_index end, | ||
582 | void (*fn)(struct queue_entry *entry)); | ||
583 | |||
584 | /** | ||
568 | * rt2x00queue_empty - Check if the queue is empty. | 585 | * rt2x00queue_empty - Check if the queue is empty. |
569 | * @queue: Queue to check if empty. | 586 | * @queue: Queue to check if empty. |
570 | */ | 587 | */ |
@@ -601,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) | |||
601 | } | 618 | } |
602 | 619 | ||
603 | /** | 620 | /** |
604 | * rt2x00queue_timeout - Check if a timeout occured for this queue | 621 | * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts |
605 | * @queue: Queue to check. | 622 | * @queue: Queue to check. |
606 | */ | 623 | */ |
607 | static inline int rt2x00queue_timeout(struct data_queue *queue) | 624 | static inline int rt2x00queue_timeout(struct data_queue *queue) |
608 | { | 625 | { |
609 | return time_after(queue->last_index, queue->last_index_done + (HZ / 10)); | 626 | return time_after(queue->last_action[Q_INDEX_DMA_DONE], |
627 | queue->last_action[Q_INDEX_DONE] + (HZ / 10)); | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * rt2x00queue_timeout - Check if a timeout occured for DMA transfers | ||
632 | * @queue: Queue to check. | ||
633 | */ | ||
634 | static inline int rt2x00queue_dma_timeout(struct data_queue *queue) | ||
635 | { | ||
636 | return time_after(queue->last_action[Q_INDEX], | ||
637 | queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10)); | ||
610 | } | 638 | } |
611 | 639 | ||
612 | /** | 640 | /** |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index ff3a36622d1b..4c5ae3d45625 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -167,137 +168,142 @@ EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); | |||
167 | /* | 168 | /* |
168 | * TX data handlers. | 169 | * TX data handlers. |
169 | */ | 170 | */ |
170 | static void rt2x00usb_interrupt_txdone(struct urb *urb) | 171 | static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) |
171 | { | 172 | { |
172 | struct queue_entry *entry = (struct queue_entry *)urb->context; | ||
173 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
174 | struct txdone_entry_desc txdesc; | ||
175 | |||
176 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || | ||
177 | !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | ||
178 | return; | ||
179 | |||
180 | /* | 173 | /* |
181 | * Obtain the status about this packet. | 174 | * If the transfer to hardware succeeded, it does not mean the |
182 | * Note that when the status is 0 it does not mean the | ||
183 | * frame was send out correctly. It only means the frame | 175 | * frame was send out correctly. It only means the frame |
184 | * was succesfully pushed to the hardware, we have no | 176 | * was succesfully pushed to the hardware, we have no |
185 | * way to determine the transmission status right now. | 177 | * way to determine the transmission status right now. |
186 | * (Only indirectly by looking at the failed TX counters | 178 | * (Only indirectly by looking at the failed TX counters |
187 | * in the register). | 179 | * in the register). |
188 | */ | 180 | */ |
189 | txdesc.flags = 0; | 181 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) |
190 | if (!urb->status) | 182 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); |
191 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | ||
192 | else | 183 | else |
193 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | 184 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); |
194 | txdesc.retry = 0; | ||
195 | |||
196 | rt2x00lib_txdone(entry, &txdesc); | ||
197 | } | 185 | } |
198 | 186 | ||
199 | static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | 187 | static void rt2x00usb_work_txdone(struct work_struct *work) |
200 | { | 188 | { |
201 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 189 | struct rt2x00_dev *rt2x00dev = |
202 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 190 | container_of(work, struct rt2x00_dev, txdone_work); |
203 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 191 | struct data_queue *queue; |
204 | u32 length; | 192 | struct queue_entry *entry; |
205 | 193 | ||
206 | if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { | 194 | tx_queue_for_each(rt2x00dev, queue) { |
207 | /* | 195 | while (!rt2x00queue_empty(queue)) { |
208 | * USB devices cannot blindly pass the skb->len as the | 196 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
209 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
210 | * to the driver to determine what the length should be. | ||
211 | */ | ||
212 | length = rt2x00dev->ops->lib->get_tx_data_len(entry); | ||
213 | 197 | ||
214 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, | 198 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
215 | usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), | 199 | break; |
216 | entry->skb->data, length, | ||
217 | rt2x00usb_interrupt_txdone, entry); | ||
218 | 200 | ||
219 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | 201 | rt2x00usb_work_txdone_entry(entry); |
202 | } | ||
220 | } | 203 | } |
221 | } | 204 | } |
222 | 205 | ||
223 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 206 | static void rt2x00usb_interrupt_txdone(struct urb *urb) |
224 | const enum data_queue_qid qid) | ||
225 | { | 207 | { |
226 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | 208 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
227 | unsigned long irqflags; | 209 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
228 | unsigned int index; | 210 | |
229 | unsigned int index_done; | 211 | if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
230 | unsigned int i; | 212 | return; |
231 | 213 | ||
232 | /* | 214 | /* |
233 | * Only protect the range we are going to loop over, | 215 | * Report the frame as DMA done |
234 | * if during our loop a extra entry is set to pending | ||
235 | * it should not be kicked during this run, since it | ||
236 | * is part of another TX operation. | ||
237 | */ | 216 | */ |
238 | spin_lock_irqsave(&queue->lock, irqflags); | 217 | rt2x00lib_dmadone(entry); |
239 | index = queue->index[Q_INDEX]; | ||
240 | index_done = queue->index[Q_INDEX_DONE]; | ||
241 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
242 | 218 | ||
243 | /* | 219 | /* |
244 | * Start from the TX done pointer, this guarentees that we will | 220 | * Check if the frame was correctly uploaded |
245 | * send out all frames in the correct order. | ||
246 | */ | 221 | */ |
247 | if (index_done < index) { | 222 | if (urb->status) |
248 | for (i = index_done; i < index; i++) | 223 | __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
249 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
250 | } else { | ||
251 | for (i = index_done; i < queue->limit; i++) | ||
252 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
253 | 224 | ||
254 | for (i = 0; i < index; i++) | 225 | /* |
255 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | 226 | * Schedule the delayed work for reading the TX status |
256 | } | 227 | * from the device. |
228 | */ | ||
229 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && | ||
230 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
231 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); | ||
232 | } | ||
233 | |||
234 | static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | ||
235 | { | ||
236 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
237 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
238 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | ||
239 | u32 length; | ||
240 | |||
241 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) | ||
242 | return; | ||
243 | |||
244 | /* | ||
245 | * USB devices cannot blindly pass the skb->len as the | ||
246 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
247 | * to the driver to determine what the length should be. | ||
248 | */ | ||
249 | length = rt2x00dev->ops->lib->get_tx_data_len(entry); | ||
250 | |||
251 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, | ||
252 | usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), | ||
253 | entry->skb->data, length, | ||
254 | rt2x00usb_interrupt_txdone, entry); | ||
255 | |||
256 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | ||
257 | } | ||
258 | |||
259 | void rt2x00usb_kick_tx_queue(struct data_queue *queue) | ||
260 | { | ||
261 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | ||
262 | rt2x00usb_kick_tx_entry); | ||
257 | } | 263 | } |
258 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); | 264 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); |
259 | 265 | ||
260 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 266 | static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) |
261 | const enum data_queue_qid qid) | ||
262 | { | 267 | { |
263 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | 268 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
264 | struct queue_entry_priv_usb *entry_priv; | 269 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
265 | struct queue_entry_priv_usb_bcn *bcn_priv; | 270 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; |
266 | unsigned int i; | 271 | |
267 | bool kill_guard; | 272 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
273 | return; | ||
274 | |||
275 | usb_kill_urb(entry_priv->urb); | ||
268 | 276 | ||
269 | /* | 277 | /* |
270 | * When killing the beacon queue, we must also kill | 278 | * Kill guardian urb (if required by driver). |
271 | * the beacon guard byte. | ||
272 | */ | 279 | */ |
273 | kill_guard = | 280 | if ((entry->queue->qid == QID_BEACON) && |
274 | (qid == QID_BEACON) && | 281 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) |
275 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)); | 282 | usb_kill_urb(bcn_priv->guardian_urb); |
276 | 283 | ||
277 | /* | 284 | /* |
278 | * Cancel all entries. | 285 | * We need a short delay here to wait for |
286 | * the URB to be canceled | ||
279 | */ | 287 | */ |
280 | for (i = 0; i < queue->limit; i++) { | 288 | do { |
281 | entry_priv = queue->entries[i].priv_data; | 289 | udelay(100); |
282 | usb_kill_urb(entry_priv->urb); | 290 | } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); |
291 | } | ||
283 | 292 | ||
284 | /* | 293 | void rt2x00usb_kill_tx_queue(struct data_queue *queue) |
285 | * Kill guardian urb (if required by driver). | 294 | { |
286 | */ | 295 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, |
287 | if (kill_guard) { | 296 | rt2x00usb_kill_tx_entry); |
288 | bcn_priv = queue->entries[i].priv_data; | ||
289 | usb_kill_urb(bcn_priv->guardian_urb); | ||
290 | } | ||
291 | } | ||
292 | } | 297 | } |
293 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); | 298 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); |
294 | 299 | ||
295 | static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | 300 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) |
296 | { | 301 | { |
297 | struct queue_entry_priv_usb *entry_priv; | 302 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
298 | unsigned short threshold = queue->threshold; | 303 | unsigned short threshold = queue->threshold; |
299 | 304 | ||
300 | WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid); | 305 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," |
306 | " invoke forced forced reset", queue->qid); | ||
301 | 307 | ||
302 | /* | 308 | /* |
303 | * Temporarily disable the TX queue, this will force mac80211 | 309 | * Temporarily disable the TX queue, this will force mac80211 |
@@ -307,20 +313,33 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | |||
307 | * queue from being enabled during the txdone handler. | 313 | * queue from being enabled during the txdone handler. |
308 | */ | 314 | */ |
309 | queue->threshold = queue->limit; | 315 | queue->threshold = queue->limit; |
310 | ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); | 316 | ieee80211_stop_queue(rt2x00dev->hw, queue->qid); |
311 | 317 | ||
312 | /* | 318 | /* |
313 | * Reset all currently uploaded TX frames. | 319 | * Kill all entries in the queue, afterwards we need to |
320 | * wait a bit for all URBs to be cancelled. | ||
314 | */ | 321 | */ |
315 | while (!rt2x00queue_empty(queue)) { | 322 | rt2x00usb_kill_tx_queue(queue); |
316 | entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data; | ||
317 | usb_kill_urb(entry_priv->urb); | ||
318 | 323 | ||
319 | /* | 324 | /* |
320 | * We need a short delay here to wait for | 325 | * In case that a driver has overriden the txdone_work |
321 | * the URB to be canceled and invoked the tx_done handler. | 326 | * function, we invoke the TX done through there. |
322 | */ | 327 | */ |
323 | udelay(200); | 328 | rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); |
329 | |||
330 | /* | ||
331 | * Security measure: if the driver did override the | ||
332 | * txdone_work function, and the hardware did arrive | ||
333 | * in a state which causes it to malfunction, it is | ||
334 | * possible that the driver couldn't handle the txdone | ||
335 | * event correctly. So after giving the driver the | ||
336 | * chance to cleanup, we now force a cleanup of any | ||
337 | * leftovers. | ||
338 | */ | ||
339 | if (!rt2x00queue_empty(queue)) { | ||
340 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," | ||
341 | " status handling failed, invoke hard reset", queue->qid); | ||
342 | rt2x00usb_work_txdone(&rt2x00dev->txdone_work); | ||
324 | } | 343 | } |
325 | 344 | ||
326 | /* | 345 | /* |
@@ -328,7 +347,15 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | |||
328 | * queue again. | 347 | * queue again. |
329 | */ | 348 | */ |
330 | queue->threshold = threshold; | 349 | queue->threshold = threshold; |
331 | ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); | 350 | ieee80211_wake_queue(rt2x00dev->hw, queue->qid); |
351 | } | ||
352 | |||
353 | static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | ||
354 | { | ||
355 | WARNING(queue->rt2x00dev, "TX queue %d status timed out," | ||
356 | " invoke forced tx handler", queue->qid); | ||
357 | |||
358 | ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); | ||
332 | } | 359 | } |
333 | 360 | ||
334 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | 361 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) |
@@ -336,8 +363,10 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
336 | struct data_queue *queue; | 363 | struct data_queue *queue; |
337 | 364 | ||
338 | tx_queue_for_each(rt2x00dev, queue) { | 365 | tx_queue_for_each(rt2x00dev, queue) { |
366 | if (rt2x00queue_dma_timeout(queue)) | ||
367 | rt2x00usb_watchdog_tx_dma(queue); | ||
339 | if (rt2x00queue_timeout(queue)) | 368 | if (rt2x00queue_timeout(queue)) |
340 | rt2x00usb_watchdog_reset_tx(queue); | 369 | rt2x00usb_watchdog_tx_status(queue); |
341 | } | 370 | } |
342 | } | 371 | } |
343 | EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); | 372 | EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); |
@@ -345,38 +374,62 @@ EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); | |||
345 | /* | 374 | /* |
346 | * RX data handlers. | 375 | * RX data handlers. |
347 | */ | 376 | */ |
377 | static void rt2x00usb_work_rxdone(struct work_struct *work) | ||
378 | { | ||
379 | struct rt2x00_dev *rt2x00dev = | ||
380 | container_of(work, struct rt2x00_dev, rxdone_work); | ||
381 | struct queue_entry *entry; | ||
382 | struct skb_frame_desc *skbdesc; | ||
383 | u8 rxd[32]; | ||
384 | |||
385 | while (!rt2x00queue_empty(rt2x00dev->rx)) { | ||
386 | entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); | ||
387 | |||
388 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | ||
389 | break; | ||
390 | |||
391 | /* | ||
392 | * Fill in desc fields of the skb descriptor | ||
393 | */ | ||
394 | skbdesc = get_skb_frame_desc(entry->skb); | ||
395 | skbdesc->desc = rxd; | ||
396 | skbdesc->desc_len = entry->queue->desc_size; | ||
397 | |||
398 | /* | ||
399 | * Send the frame to rt2x00lib for further processing. | ||
400 | */ | ||
401 | rt2x00lib_rxdone(rt2x00dev, entry); | ||
402 | } | ||
403 | } | ||
404 | |||
348 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | 405 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) |
349 | { | 406 | { |
350 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 407 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
351 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 408 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
352 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
353 | u8 rxd[32]; | ||
354 | 409 | ||
355 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || | 410 | if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
356 | !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | ||
357 | return; | 411 | return; |
358 | 412 | ||
359 | /* | 413 | /* |
360 | * Check if the received data is simply too small | 414 | * Report the frame as DMA done |
361 | * to be actually valid, or if the urb is signaling | ||
362 | * a problem. | ||
363 | */ | 415 | */ |
364 | if (urb->actual_length < entry->queue->desc_size || urb->status) { | 416 | rt2x00lib_dmadone(entry); |
365 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
366 | usb_submit_urb(urb, GFP_ATOMIC); | ||
367 | return; | ||
368 | } | ||
369 | 417 | ||
370 | /* | 418 | /* |
371 | * Fill in desc fields of the skb descriptor | 419 | * Check if the received data is simply too small |
420 | * to be actually valid, or if the urb is signaling | ||
421 | * a problem. | ||
372 | */ | 422 | */ |
373 | skbdesc->desc = rxd; | 423 | if (urb->actual_length < entry->queue->desc_size || urb->status) |
374 | skbdesc->desc_len = entry->queue->desc_size; | 424 | __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
375 | 425 | ||
376 | /* | 426 | /* |
377 | * Send the frame to rt2x00lib for further processing. | 427 | * Schedule the delayed work for reading the RX status |
428 | * from the device. | ||
378 | */ | 429 | */ |
379 | rt2x00lib_rxdone(rt2x00dev, entry); | 430 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && |
431 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
432 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); | ||
380 | } | 433 | } |
381 | 434 | ||
382 | /* | 435 | /* |
@@ -391,7 +444,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
391 | * The USB version of kill_tx_queue also works | 444 | * The USB version of kill_tx_queue also works |
392 | * on the RX queue. | 445 | * on the RX queue. |
393 | */ | 446 | */ |
394 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX); | 447 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx); |
395 | } | 448 | } |
396 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 449 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
397 | 450 | ||
@@ -405,6 +458,8 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) | |||
405 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 458 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
406 | int pipe; | 459 | int pipe; |
407 | 460 | ||
461 | entry->flags = 0; | ||
462 | |||
408 | if (entry->queue->qid == QID_RX) { | 463 | if (entry->queue->qid == QID_RX) { |
409 | pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); | 464 | pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); |
410 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe, | 465 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe, |
@@ -413,8 +468,6 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) | |||
413 | 468 | ||
414 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 469 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
415 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | 470 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); |
416 | } else { | ||
417 | entry->flags = 0; | ||
418 | } | 471 | } |
419 | } | 472 | } |
420 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); | 473 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); |
@@ -659,6 +712,9 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
659 | 712 | ||
660 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); | 713 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); |
661 | 714 | ||
715 | INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); | ||
716 | INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); | ||
717 | |||
662 | retval = rt2x00usb_alloc_reg(rt2x00dev); | 718 | retval = rt2x00usb_alloc_reg(rt2x00dev); |
663 | if (retval) | 719 | if (retval) |
664 | goto exit_free_device; | 720 | goto exit_free_device; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index d3d3ddc40875..c2d997f67b3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -379,25 +379,21 @@ struct queue_entry_priv_usb_bcn { | |||
379 | 379 | ||
380 | /** | 380 | /** |
381 | * rt2x00usb_kick_tx_queue - Kick data queue | 381 | * rt2x00usb_kick_tx_queue - Kick data queue |
382 | * @rt2x00dev: Pointer to &struct rt2x00_dev | 382 | * @queue: Data queue to kick |
383 | * @qid: Data queue to kick | ||
384 | * | 383 | * |
385 | * This will walk through all entries of the queue and push all pending | 384 | * This will walk through all entries of the queue and push all pending |
386 | * frames to the hardware as a single burst. | 385 | * frames to the hardware as a single burst. |
387 | */ | 386 | */ |
388 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 387 | void rt2x00usb_kick_tx_queue(struct data_queue *queue); |
389 | const enum data_queue_qid qid); | ||
390 | 388 | ||
391 | /** | 389 | /** |
392 | * rt2x00usb_kill_tx_queue - Kill data queue | 390 | * rt2x00usb_kill_tx_queue - Kill data queue |
393 | * @rt2x00dev: Pointer to &struct rt2x00_dev | 391 | * @queue: Data queue to kill |
394 | * @qid: Data queue to kill | ||
395 | * | 392 | * |
396 | * This will walk through all entries of the queue and kill all | 393 | * This will walk through all entries of the queue and kill all |
397 | * previously kicked frames before they can be send. | 394 | * previously kicked frames before they can be send. |
398 | */ | 395 | */ |
399 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 396 | void rt2x00usb_kill_tx_queue(struct data_queue *queue); |
400 | const enum data_queue_qid qid); | ||
401 | 397 | ||
402 | /** | 398 | /** |
403 | * rt2x00usb_watchdog - Watchdog for USB communication | 399 | * rt2x00usb_watchdog - Watchdog for USB communication |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e539c6cb636f..97b3935f615b 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -594,7 +594,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
594 | } | 594 | } |
595 | 595 | ||
596 | static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, | 596 | static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, |
597 | struct rt2x00lib_erp *erp) | 597 | struct rt2x00lib_erp *erp, |
598 | u32 changed) | ||
598 | { | 599 | { |
599 | u32 reg; | 600 | u32 reg; |
600 | 601 | ||
@@ -603,28 +604,36 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
603 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); | 604 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); |
604 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 605 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
605 | 606 | ||
606 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | 607 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
607 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); | 608 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); |
608 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 609 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); |
609 | !!erp->short_preamble); | 610 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
610 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 611 | !!erp->short_preamble); |
612 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
613 | } | ||
611 | 614 | ||
612 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); | 615 | if (changed & BSS_CHANGED_BASIC_RATES) |
616 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, | ||
617 | erp->basic_rates); | ||
613 | 618 | ||
614 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 619 | if (changed & BSS_CHANGED_BEACON_INT) { |
615 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, | 620 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
616 | erp->beacon_int * 16); | 621 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, |
617 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 622 | erp->beacon_int * 16); |
623 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
624 | } | ||
618 | 625 | ||
619 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | 626 | if (changed & BSS_CHANGED_ERP_SLOT) { |
620 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); | 627 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); |
621 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | 628 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); |
629 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | ||
622 | 630 | ||
623 | rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); | 631 | rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); |
624 | rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); | 632 | rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); |
625 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); | 633 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); |
626 | rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); | 634 | rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); |
627 | rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); | 635 | rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); |
636 | } | ||
628 | } | 637 | } |
629 | 638 | ||
630 | static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | 639 | static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, |
@@ -1050,7 +1059,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, | |||
1050 | /* | 1059 | /* |
1051 | * Determine r17 bounds. | 1060 | * Determine r17 bounds. |
1052 | */ | 1061 | */ |
1053 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { | 1062 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
1054 | low_bound = 0x28; | 1063 | low_bound = 0x28; |
1055 | up_bound = 0x48; | 1064 | up_bound = 0x48; |
1056 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1065 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
@@ -1645,6 +1654,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
1645 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 1654 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); |
1646 | rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); | 1655 | rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); |
1647 | rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); | 1656 | rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); |
1657 | rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask); | ||
1648 | rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); | 1658 | rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); |
1649 | rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); | 1659 | rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); |
1650 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 1660 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); |
@@ -1658,6 +1668,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
1658 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask); | 1668 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask); |
1659 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); | 1669 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); |
1660 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); | 1670 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); |
1671 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); | ||
1661 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | 1672 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); |
1662 | } | 1673 | } |
1663 | 1674 | ||
@@ -1766,12 +1777,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1766 | /* | 1777 | /* |
1767 | * TX descriptor initialization | 1778 | * TX descriptor initialization |
1768 | */ | 1779 | */ |
1769 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1780 | static void rt61pci_write_tx_desc(struct queue_entry *entry, |
1770 | struct sk_buff *skb, | ||
1771 | struct txentry_desc *txdesc) | 1781 | struct txentry_desc *txdesc) |
1772 | { | 1782 | { |
1773 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1783 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1774 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1784 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1775 | __le32 *txd = entry_priv->desc; | 1785 | __le32 *txd = entry_priv->desc; |
1776 | u32 word; | 1786 | u32 word; |
1777 | 1787 | ||
@@ -1779,7 +1789,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1779 | * Start writing the descriptor words. | 1789 | * Start writing the descriptor words. |
1780 | */ | 1790 | */ |
1781 | rt2x00_desc_read(txd, 1, &word); | 1791 | rt2x00_desc_read(txd, 1, &word); |
1782 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); | 1792 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); |
1783 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); | 1793 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1784 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1794 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1785 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1795 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
@@ -1802,15 +1812,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1802 | } | 1812 | } |
1803 | 1813 | ||
1804 | rt2x00_desc_read(txd, 5, &word); | 1814 | rt2x00_desc_read(txd, 5, &word); |
1805 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); | 1815 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); |
1806 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, | 1816 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, |
1807 | skbdesc->entry->entry_idx); | 1817 | skbdesc->entry->entry_idx); |
1808 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1818 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1809 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); | 1819 | TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); |
1810 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1820 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1811 | rt2x00_desc_write(txd, 5, word); | 1821 | rt2x00_desc_write(txd, 5, word); |
1812 | 1822 | ||
1813 | if (txdesc->queue != QID_BEACON) { | 1823 | if (txdesc->qid != QID_BEACON) { |
1814 | rt2x00_desc_read(txd, 6, &word); | 1824 | rt2x00_desc_read(txd, 6, &word); |
1815 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1825 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1816 | skbdesc->skb_dma); | 1826 | skbdesc->skb_dma); |
@@ -1857,7 +1867,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1857 | */ | 1867 | */ |
1858 | skbdesc->desc = txd; | 1868 | skbdesc->desc = txd; |
1859 | skbdesc->desc_len = | 1869 | skbdesc->desc_len = |
1860 | (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; | 1870 | (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; |
1861 | } | 1871 | } |
1862 | 1872 | ||
1863 | /* | 1873 | /* |
@@ -1882,7 +1892,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
1882 | /* | 1892 | /* |
1883 | * Write the TX descriptor for the beacon. | 1893 | * Write the TX descriptor for the beacon. |
1884 | */ | 1894 | */ |
1885 | rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1895 | rt61pci_write_tx_desc(entry, txdesc); |
1886 | 1896 | ||
1887 | /* | 1897 | /* |
1888 | * Dump beacon to userspace through debugfs. | 1898 | * Dump beacon to userspace through debugfs. |
@@ -1918,34 +1928,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
1918 | entry->skb = NULL; | 1928 | entry->skb = NULL; |
1919 | } | 1929 | } |
1920 | 1930 | ||
1921 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1931 | static void rt61pci_kick_tx_queue(struct data_queue *queue) |
1922 | const enum data_queue_qid queue) | ||
1923 | { | 1932 | { |
1933 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1924 | u32 reg; | 1934 | u32 reg; |
1925 | 1935 | ||
1926 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1936 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
1927 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); | 1937 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); |
1928 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); | 1938 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); |
1929 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI)); | 1939 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); |
1930 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO)); | 1940 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO)); |
1931 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1941 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1932 | } | 1942 | } |
1933 | 1943 | ||
1934 | static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 1944 | static void rt61pci_kill_tx_queue(struct data_queue *queue) |
1935 | const enum data_queue_qid qid) | ||
1936 | { | 1945 | { |
1946 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1937 | u32 reg; | 1947 | u32 reg; |
1938 | 1948 | ||
1939 | if (qid == QID_BEACON) { | 1949 | if (queue->qid == QID_BEACON) { |
1940 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | 1950 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); |
1941 | return; | 1951 | return; |
1942 | } | 1952 | } |
1943 | 1953 | ||
1944 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1954 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
1945 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE)); | 1955 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); |
1946 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK)); | 1956 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); |
1947 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI)); | 1957 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); |
1948 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO)); | 1958 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO)); |
1949 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1959 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1950 | } | 1960 | } |
1951 | 1961 | ||
@@ -1972,7 +1982,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1972 | return 0; | 1982 | return 0; |
1973 | } | 1983 | } |
1974 | 1984 | ||
1975 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { | 1985 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
1976 | if (lna == 3 || lna == 2) | 1986 | if (lna == 3 || lna == 2) |
1977 | offset += 10; | 1987 | offset += 10; |
1978 | } | 1988 | } |
@@ -2107,11 +2117,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2107 | "TX status report missed for entry %d\n", | 2117 | "TX status report missed for entry %d\n", |
2108 | entry_done->entry_idx); | 2118 | entry_done->entry_idx); |
2109 | 2119 | ||
2110 | txdesc.flags = 0; | 2120 | rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN); |
2111 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | ||
2112 | txdesc.retry = 0; | ||
2113 | |||
2114 | rt2x00lib_txdone(entry_done, &txdesc); | ||
2115 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 2121 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
2116 | } | 2122 | } |
2117 | 2123 | ||
@@ -2654,20 +2660,24 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2654 | /* | 2660 | /* |
2655 | * Create channel information array | 2661 | * Create channel information array |
2656 | */ | 2662 | */ |
2657 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 2663 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
2658 | if (!info) | 2664 | if (!info) |
2659 | return -ENOMEM; | 2665 | return -ENOMEM; |
2660 | 2666 | ||
2661 | spec->channels_info = info; | 2667 | spec->channels_info = info; |
2662 | 2668 | ||
2663 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | 2669 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); |
2664 | for (i = 0; i < 14; i++) | 2670 | for (i = 0; i < 14; i++) { |
2665 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2671 | info[i].max_power = MAX_TXPOWER; |
2672 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2673 | } | ||
2666 | 2674 | ||
2667 | if (spec->num_channels > 14) { | 2675 | if (spec->num_channels > 14) { |
2668 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2676 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
2669 | for (i = 14; i < spec->num_channels; i++) | 2677 | for (i = 14; i < spec->num_channels; i++) { |
2670 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2678 | info[i].max_power = MAX_TXPOWER; |
2679 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2680 | } | ||
2671 | } | 2681 | } |
2672 | 2682 | ||
2673 | return 0; | 2683 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index aa9de18fd410..e22f01c1818e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -545,7 +545,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
545 | } | 545 | } |
546 | 546 | ||
547 | static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, | 547 | static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, |
548 | struct rt2x00lib_erp *erp) | 548 | struct rt2x00lib_erp *erp, |
549 | u32 changed) | ||
549 | { | 550 | { |
550 | u32 reg; | 551 | u32 reg; |
551 | 552 | ||
@@ -554,28 +555,36 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, | |||
554 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); | 555 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); |
555 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 556 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
556 | 557 | ||
557 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); | 558 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
558 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); | 559 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); |
559 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 560 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); |
560 | !!erp->short_preamble); | 561 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
561 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 562 | !!erp->short_preamble); |
563 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
564 | } | ||
562 | 565 | ||
563 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); | 566 | if (changed & BSS_CHANGED_BASIC_RATES) |
567 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, | ||
568 | erp->basic_rates); | ||
564 | 569 | ||
565 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 570 | if (changed & BSS_CHANGED_BEACON_INT) { |
566 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, | 571 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
567 | erp->beacon_int * 16); | 572 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, |
568 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 573 | erp->beacon_int * 16); |
574 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
575 | } | ||
569 | 576 | ||
570 | rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); | 577 | if (changed & BSS_CHANGED_ERP_SLOT) { |
571 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); | 578 | rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); |
572 | rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); | 579 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); |
580 | rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); | ||
573 | 581 | ||
574 | rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); | 582 | rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); |
575 | rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); | 583 | rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); |
576 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); | 584 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); |
577 | rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); | 585 | rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); |
578 | rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); | 586 | rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); |
587 | } | ||
579 | } | 588 | } |
580 | 589 | ||
581 | static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | 590 | static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, |
@@ -929,7 +938,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, | |||
929 | /* | 938 | /* |
930 | * Determine r17 bounds. | 939 | * Determine r17 bounds. |
931 | */ | 940 | */ |
932 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { | 941 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
933 | low_bound = 0x28; | 942 | low_bound = 0x28; |
934 | up_bound = 0x48; | 943 | up_bound = 0x48; |
935 | 944 | ||
@@ -1426,12 +1435,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1426 | /* | 1435 | /* |
1427 | * TX descriptor initialization | 1436 | * TX descriptor initialization |
1428 | */ | 1437 | */ |
1429 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1438 | static void rt73usb_write_tx_desc(struct queue_entry *entry, |
1430 | struct sk_buff *skb, | ||
1431 | struct txentry_desc *txdesc) | 1439 | struct txentry_desc *txdesc) |
1432 | { | 1440 | { |
1433 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1441 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1434 | __le32 *txd = (__le32 *) skb->data; | 1442 | __le32 *txd = (__le32 *) entry->skb->data; |
1435 | u32 word; | 1443 | u32 word; |
1436 | 1444 | ||
1437 | /* | 1445 | /* |
@@ -1464,7 +1472,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1464 | rt2x00_desc_write(txd, 0, word); | 1472 | rt2x00_desc_write(txd, 0, word); |
1465 | 1473 | ||
1466 | rt2x00_desc_read(txd, 1, &word); | 1474 | rt2x00_desc_read(txd, 1, &word); |
1467 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); | 1475 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); |
1468 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); | 1476 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1469 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1477 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1470 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1478 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
@@ -1487,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1487 | 1495 | ||
1488 | rt2x00_desc_read(txd, 5, &word); | 1496 | rt2x00_desc_read(txd, 5, &word); |
1489 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1497 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1490 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); | 1498 | TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); |
1491 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1499 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1492 | rt2x00_desc_write(txd, 5, word); | 1500 | rt2x00_desc_write(txd, 5, word); |
1493 | 1501 | ||
@@ -1526,7 +1534,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1526 | /* | 1534 | /* |
1527 | * Write the TX descriptor for the beacon. | 1535 | * Write the TX descriptor for the beacon. |
1528 | */ | 1536 | */ |
1529 | rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1537 | rt73usb_write_tx_desc(entry, txdesc); |
1530 | 1538 | ||
1531 | /* | 1539 | /* |
1532 | * Dump beacon to userspace through debugfs. | 1540 | * Dump beacon to userspace through debugfs. |
@@ -1574,6 +1582,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry) | |||
1574 | return length; | 1582 | return length; |
1575 | } | 1583 | } |
1576 | 1584 | ||
1585 | static void rt73usb_kill_tx_queue(struct data_queue *queue) | ||
1586 | { | ||
1587 | if (queue->qid == QID_BEACON) | ||
1588 | rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); | ||
1589 | |||
1590 | rt2x00usb_kill_tx_queue(queue); | ||
1591 | } | ||
1592 | |||
1577 | /* | 1593 | /* |
1578 | * RX control handlers | 1594 | * RX control handlers |
1579 | */ | 1595 | */ |
@@ -1597,7 +1613,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1597 | return 0; | 1613 | return 0; |
1598 | } | 1614 | } |
1599 | 1615 | ||
1600 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { | 1616 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
1601 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1617 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
1602 | if (lna == 3 || lna == 2) | 1618 | if (lna == 3 || lna == 2) |
1603 | offset += 10; | 1619 | offset += 10; |
@@ -2084,20 +2100,24 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2084 | /* | 2100 | /* |
2085 | * Create channel information array | 2101 | * Create channel information array |
2086 | */ | 2102 | */ |
2087 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 2103 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
2088 | if (!info) | 2104 | if (!info) |
2089 | return -ENOMEM; | 2105 | return -ENOMEM; |
2090 | 2106 | ||
2091 | spec->channels_info = info; | 2107 | spec->channels_info = info; |
2092 | 2108 | ||
2093 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | 2109 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); |
2094 | for (i = 0; i < 14; i++) | 2110 | for (i = 0; i < 14; i++) { |
2095 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2111 | info[i].max_power = MAX_TXPOWER; |
2112 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2113 | } | ||
2096 | 2114 | ||
2097 | if (spec->num_channels > 14) { | 2115 | if (spec->num_channels > 14) { |
2098 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2116 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
2099 | for (i = 14; i < spec->num_channels; i++) | 2117 | for (i = 14; i < spec->num_channels; i++) { |
2100 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2118 | info[i].max_power = MAX_TXPOWER; |
2119 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2120 | } | ||
2101 | } | 2121 | } |
2102 | 2122 | ||
2103 | return 0; | 2123 | return 0; |
@@ -2259,7 +2279,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2259 | .write_beacon = rt73usb_write_beacon, | 2279 | .write_beacon = rt73usb_write_beacon, |
2260 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2280 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2261 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 2281 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
2262 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 2282 | .kill_tx_queue = rt73usb_kill_tx_queue, |
2263 | .fill_rxdone = rt73usb_fill_rxdone, | 2283 | .fill_rxdone = rt73usb_fill_rxdone, |
2264 | .config_shared_key = rt73usb_config_shared_key, | 2284 | .config_shared_key = rt73usb_config_shared_key, |
2265 | .config_pairwise_key = rt73usb_config_pairwise_key, | 2285 | .config_pairwise_key = rt73usb_config_pairwise_key, |