diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800lib.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 305 |
1 files changed, 228 insertions, 77 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6a0cb2d924d8..27a6e225083c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -255,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
255 | } | 255 | } |
256 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); | 256 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); |
257 | 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 | |||
258 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | 275 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) |
259 | { | 276 | { |
260 | unsigned int i; | 277 | unsigned int i; |
@@ -368,19 +385,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
368 | u32 reg; | 385 | u32 reg; |
369 | 386 | ||
370 | /* | 387 | /* |
371 | * 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. | ||
372 | */ | 390 | */ |
373 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 391 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); |
374 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
375 | if (reg && reg != ~0) | ||
376 | break; | ||
377 | msleep(1); | ||
378 | } | ||
379 | 392 | ||
380 | if (i == REGISTER_BUSY_COUNT) { | 393 | /* |
381 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 394 | * Wait for stable hardware. |
395 | */ | ||
396 | if (rt2800_wait_csr_ready(rt2x00dev)) | ||
382 | return -EBUSY; | 397 | return -EBUSY; |
383 | } | ||
384 | 398 | ||
385 | if (rt2x00_is_pci(rt2x00dev)) | 399 | if (rt2x00_is_pci(rt2x00dev)) |
386 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | 400 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); |
@@ -469,7 +483,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
469 | txdesc->key_idx : 0xff); | 483 | txdesc->key_idx : 0xff); |
470 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 484 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
471 | txdesc->length); | 485 | txdesc->length); |
472 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); | 486 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); |
473 | rt2x00_desc_write(txwi, 1, word); | 487 | rt2x00_desc_write(txwi, 1, word); |
474 | 488 | ||
475 | /* | 489 | /* |
@@ -573,6 +587,49 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |||
573 | } | 587 | } |
574 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 588 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
575 | 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 | |||
576 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | 633 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) |
577 | { | 634 | { |
578 | struct data_queue *queue; | 635 | struct data_queue *queue; |
@@ -581,8 +638,8 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
581 | struct txdone_entry_desc txdesc; | 638 | struct txdone_entry_desc txdesc; |
582 | u32 word; | 639 | u32 word; |
583 | u32 reg; | 640 | u32 reg; |
584 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; | ||
585 | u16 mcs, real_mcs; | 641 | u16 mcs, real_mcs; |
642 | u8 pid; | ||
586 | int i; | 643 | int i; |
587 | 644 | ||
588 | /* | 645 | /* |
@@ -599,18 +656,15 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
599 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | 656 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) |
600 | break; | 657 | break; |
601 | 658 | ||
602 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
603 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
604 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
605 | |||
606 | /* | 659 | /* |
607 | * Skip this entry when it contains an invalid | 660 | * Skip this entry when it contains an invalid |
608 | * queue identication number. | 661 | * queue identication number. |
609 | */ | 662 | */ |
610 | if (pid <= 0 || pid > QID_RX) | 663 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; |
664 | if (pid >= QID_RX) | ||
611 | continue; | 665 | continue; |
612 | 666 | ||
613 | queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); | 667 | queue = rt2x00queue_get_queue(rt2x00dev, pid); |
614 | if (unlikely(!queue)) | 668 | if (unlikely(!queue)) |
615 | continue; | 669 | continue; |
616 | 670 | ||
@@ -619,38 +673,24 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
619 | * order. We first check that the queue is not empty. | 673 | * order. We first check that the queue is not empty. |
620 | */ | 674 | */ |
621 | entry = NULL; | 675 | entry = NULL; |
676 | txwi = NULL; | ||
622 | while (!rt2x00queue_empty(queue)) { | 677 | while (!rt2x00queue_empty(queue)) { |
623 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 678 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
624 | if (!test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | 679 | if (rt2800_txdone_entry_check(entry, reg)) |
625 | break; | 680 | break; |
626 | |||
627 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
628 | } | 681 | } |
629 | 682 | ||
630 | if (!entry || rt2x00queue_empty(queue)) | 683 | if (!entry || rt2x00queue_empty(queue)) |
631 | break; | 684 | break; |
632 | 685 | ||
633 | /* | ||
634 | * Check if we got a match by looking at WCID/ACK/PID | ||
635 | * fields | ||
636 | */ | ||
637 | txwi = rt2800_drv_get_txwi(entry); | ||
638 | |||
639 | rt2x00_desc_read(txwi, 1, &word); | ||
640 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
641 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
642 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
643 | |||
644 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) | ||
645 | WARNING(rt2x00dev, "invalid TX_STA_FIFO content"); | ||
646 | 686 | ||
647 | /* | 687 | /* |
648 | * Obtain the status about this packet. | 688 | * Obtain the status about this packet. |
649 | */ | 689 | */ |
650 | txdesc.flags = 0; | 690 | txdesc.flags = 0; |
691 | txwi = rt2800_drv_get_txwi(entry); | ||
651 | rt2x00_desc_read(txwi, 0, &word); | 692 | rt2x00_desc_read(txwi, 0, &word); |
652 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | 693 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); |
653 | mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | ||
654 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | 694 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); |
655 | 695 | ||
656 | /* | 696 | /* |
@@ -1095,19 +1135,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
1095 | } | 1135 | } |
1096 | 1136 | ||
1097 | if (flags & CONFIG_UPDATE_MAC) { | 1137 | if (flags & CONFIG_UPDATE_MAC) { |
1098 | reg = le32_to_cpu(conf->mac[1]); | 1138 | if (!is_zero_ether_addr((const u8 *)conf->mac)) { |
1099 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); | 1139 | reg = le32_to_cpu(conf->mac[1]); |
1100 | 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 | } | ||
1101 | 1143 | ||
1102 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, | 1144 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, |
1103 | conf->mac, sizeof(conf->mac)); | 1145 | conf->mac, sizeof(conf->mac)); |
1104 | } | 1146 | } |
1105 | 1147 | ||
1106 | if (flags & CONFIG_UPDATE_BSSID) { | 1148 | if (flags & CONFIG_UPDATE_BSSID) { |
1107 | reg = le32_to_cpu(conf->bssid[1]); | 1149 | if (!is_zero_ether_addr((const u8 *)conf->bssid)) { |
1108 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); | 1150 | reg = le32_to_cpu(conf->bssid[1]); |
1109 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); | 1151 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); |
1110 | 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 | } | ||
1111 | 1155 | ||
1112 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, | 1156 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, |
1113 | conf->bssid, sizeof(conf->bssid)); | 1157 | conf->bssid, sizeof(conf->bssid)); |
@@ -1240,27 +1284,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, | |||
1240 | * double meaning, and we should set a 7DBm boost flag. | 1284 | * double meaning, and we should set a 7DBm boost flag. |
1241 | */ | 1285 | */ |
1242 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, | 1286 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, |
1243 | (info->tx_power1 >= 0)); | 1287 | (info->default_power1 >= 0)); |
1244 | 1288 | ||
1245 | if (info->tx_power1 < 0) | 1289 | if (info->default_power1 < 0) |
1246 | info->tx_power1 += 7; | 1290 | info->default_power1 += 7; |
1247 | 1291 | ||
1248 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, | 1292 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1); |
1249 | TXPOWER_A_TO_DEV(info->tx_power1)); | ||
1250 | 1293 | ||
1251 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, | 1294 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, |
1252 | (info->tx_power2 >= 0)); | 1295 | (info->default_power2 >= 0)); |
1253 | 1296 | ||
1254 | if (info->tx_power2 < 0) | 1297 | if (info->default_power2 < 0) |
1255 | info->tx_power2 += 7; | 1298 | info->default_power2 += 7; |
1256 | 1299 | ||
1257 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, | 1300 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2); |
1258 | TXPOWER_A_TO_DEV(info->tx_power2)); | ||
1259 | } else { | 1301 | } else { |
1260 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, | 1302 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1); |
1261 | TXPOWER_G_TO_DEV(info->tx_power1)); | 1303 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2); |
1262 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, | ||
1263 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1264 | } | 1304 | } |
1265 | 1305 | ||
1266 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); | 1306 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); |
@@ -1300,13 +1340,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1300 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | 1340 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); |
1301 | 1341 | ||
1302 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); | 1342 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); |
1303 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | 1343 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1); |
1304 | TXPOWER_G_TO_DEV(info->tx_power1)); | ||
1305 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | 1344 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); |
1306 | 1345 | ||
1307 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); | 1346 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); |
1308 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | 1347 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); |
1309 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1310 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); | 1348 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); |
1311 | 1349 | ||
1312 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | 1350 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); |
@@ -1330,10 +1368,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1330 | unsigned int tx_pin; | 1368 | unsigned int tx_pin; |
1331 | u8 bbp; | 1369 | u8 bbp; |
1332 | 1370 | ||
1371 | if (rf->channel <= 14) { | ||
1372 | info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); | ||
1373 | info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); | ||
1374 | } else { | ||
1375 | info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); | ||
1376 | info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); | ||
1377 | } | ||
1378 | |||
1333 | if (rt2x00_rf(rt2x00dev, RF2020) || | 1379 | if (rt2x00_rf(rt2x00dev, RF2020) || |
1334 | rt2x00_rf(rt2x00dev, RF3020) || | 1380 | rt2x00_rf(rt2x00dev, RF3020) || |
1335 | rt2x00_rf(rt2x00dev, RF3021) || | 1381 | rt2x00_rf(rt2x00dev, RF3021) || |
1336 | rt2x00_rf(rt2x00dev, RF3022)) | 1382 | rt2x00_rf(rt2x00dev, RF3022) || |
1383 | rt2x00_rf(rt2x00dev, RF3052)) | ||
1337 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1384 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
1338 | else | 1385 | else |
1339 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | 1386 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); |
@@ -1656,7 +1703,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); | |||
1656 | /* | 1703 | /* |
1657 | * Initialization functions. | 1704 | * Initialization functions. |
1658 | */ | 1705 | */ |
1659 | int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | 1706 | static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) |
1660 | { | 1707 | { |
1661 | u32 reg; | 1708 | u32 reg; |
1662 | u16 eeprom; | 1709 | u16 eeprom; |
@@ -2026,7 +2073,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2026 | 2073 | ||
2027 | return 0; | 2074 | return 0; |
2028 | } | 2075 | } |
2029 | EXPORT_SYMBOL_GPL(rt2800_init_registers); | ||
2030 | 2076 | ||
2031 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) | 2077 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) |
2032 | { | 2078 | { |
@@ -2069,7 +2115,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
2069 | return -EACCES; | 2115 | return -EACCES; |
2070 | } | 2116 | } |
2071 | 2117 | ||
2072 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | 2118 | static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) |
2073 | { | 2119 | { |
2074 | unsigned int i; | 2120 | unsigned int i; |
2075 | u16 eeprom; | 2121 | u16 eeprom; |
@@ -2164,7 +2210,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2164 | 2210 | ||
2165 | return 0; | 2211 | return 0; |
2166 | } | 2212 | } |
2167 | EXPORT_SYMBOL_GPL(rt2800_init_bbp); | ||
2168 | 2213 | ||
2169 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | 2214 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, |
2170 | bool bw40, u8 rfcsr24, u8 filter_target) | 2215 | bool bw40, u8 rfcsr24, u8 filter_target) |
@@ -2226,7 +2271,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
2226 | return rfcsr24; | 2271 | return rfcsr24; |
2227 | } | 2272 | } |
2228 | 2273 | ||
2229 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | 2274 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) |
2230 | { | 2275 | { |
2231 | u8 rfcsr; | 2276 | u8 rfcsr; |
2232 | u8 bbp; | 2277 | u8 bbp; |
@@ -2480,7 +2525,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2480 | 2525 | ||
2481 | return 0; | 2526 | return 0; |
2482 | } | 2527 | } |
2483 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); | 2528 | |
2529 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
2530 | { | ||
2531 | u32 reg; | ||
2532 | u16 word; | ||
2533 | |||
2534 | /* | ||
2535 | * Initialize all registers. | ||
2536 | */ | ||
2537 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | ||
2538 | rt2800_init_registers(rt2x00dev) || | ||
2539 | rt2800_init_bbp(rt2x00dev) || | ||
2540 | rt2800_init_rfcsr(rt2x00dev))) | ||
2541 | return -EIO; | ||
2542 | |||
2543 | /* | ||
2544 | * Send signal to firmware during boot time. | ||
2545 | */ | ||
2546 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
2547 | |||
2548 | if (rt2x00_is_usb(rt2x00dev) && | ||
2549 | (rt2x00_rt(rt2x00dev, RT3070) || | ||
2550 | rt2x00_rt(rt2x00dev, RT3071) || | ||
2551 | rt2x00_rt(rt2x00dev, RT3572))) { | ||
2552 | udelay(200); | ||
2553 | rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); | ||
2554 | udelay(10); | ||
2555 | } | ||
2556 | |||
2557 | /* | ||
2558 | * Enable RX. | ||
2559 | */ | ||
2560 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2561 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
2562 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
2563 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2564 | |||
2565 | udelay(50); | ||
2566 | |||
2567 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
2568 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
2569 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
2570 | rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); | ||
2571 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
2572 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
2573 | |||
2574 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2575 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
2576 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
2577 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2578 | |||
2579 | /* | ||
2580 | * Initialize LED control | ||
2581 | */ | ||
2582 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
2583 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
2584 | word & 0xff, (word >> 8) & 0xff); | ||
2585 | |||
2586 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
2587 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
2588 | word & 0xff, (word >> 8) & 0xff); | ||
2589 | |||
2590 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
2591 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
2592 | word & 0xff, (word >> 8) & 0xff); | ||
2593 | |||
2594 | return 0; | ||
2595 | } | ||
2596 | EXPORT_SYMBOL_GPL(rt2800_enable_radio); | ||
2597 | |||
2598 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
2599 | { | ||
2600 | u32 reg; | ||
2601 | |||
2602 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
2603 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
2604 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); | ||
2605 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
2606 | rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); | ||
2607 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
2608 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
2609 | |||
2610 | /* Wait for DMA, ignore error */ | ||
2611 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
2612 | |||
2613 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2614 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); | ||
2615 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
2616 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2617 | |||
2618 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
2619 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
2620 | } | ||
2621 | EXPORT_SYMBOL_GPL(rt2800_disable_radio); | ||
2484 | 2622 | ||
2485 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) | 2623 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) |
2486 | { | 2624 | { |
@@ -2636,6 +2774,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2636 | default_lna_gain); | 2774 | default_lna_gain); |
2637 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | 2775 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); |
2638 | 2776 | ||
2777 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); | ||
2778 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) | ||
2779 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); | ||
2780 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) | ||
2781 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); | ||
2782 | rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); | ||
2783 | |||
2639 | return 0; | 2784 | return 0; |
2640 | } | 2785 | } |
2641 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); | 2786 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); |
@@ -2875,9 +3020,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2875 | { | 3020 | { |
2876 | struct hw_mode_spec *spec = &rt2x00dev->spec; | 3021 | struct hw_mode_spec *spec = &rt2x00dev->spec; |
2877 | struct channel_info *info; | 3022 | struct channel_info *info; |
2878 | char *tx_power1; | 3023 | char *default_power1; |
2879 | char *tx_power2; | 3024 | char *default_power2; |
2880 | unsigned int i; | 3025 | unsigned int i; |
3026 | unsigned short max_power; | ||
2881 | u16 eeprom; | 3027 | u16 eeprom; |
2882 | 3028 | ||
2883 | /* | 3029 | /* |
@@ -2991,21 +3137,26 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2991 | 3137 | ||
2992 | spec->channels_info = info; | 3138 | spec->channels_info = info; |
2993 | 3139 | ||
2994 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | 3140 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); |
2995 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | 3141 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); |
3142 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
3143 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
2996 | 3144 | ||
2997 | for (i = 0; i < 14; i++) { | 3145 | for (i = 0; i < 14; i++) { |
2998 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | 3146 | info[i].max_power = max_power; |
2999 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | 3147 | info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); |
3148 | info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); | ||
3000 | } | 3149 | } |
3001 | 3150 | ||
3002 | if (spec->num_channels > 14) { | 3151 | if (spec->num_channels > 14) { |
3003 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | 3152 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); |
3004 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 3153 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); |
3154 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
3005 | 3155 | ||
3006 | for (i = 14; i < spec->num_channels; i++) { | 3156 | for (i = 14; i < spec->num_channels; i++) { |
3007 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | 3157 | info[i].max_power = max_power; |
3008 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | 3158 | info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); |
3159 | info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); | ||
3009 | } | 3160 | } |
3010 | } | 3161 | } |
3011 | 3162 | ||