diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 176 |
1 files changed, 44 insertions, 132 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index e3f3a97db807..8ad0669a1b99 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -401,59 +401,15 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
| 401 | { | 401 | { |
| 402 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 402 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
| 403 | __le32 *txi = skbdesc->desc; | 403 | __le32 *txi = skbdesc->desc; |
| 404 | __le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)]; | ||
| 405 | u32 word; | 404 | u32 word; |
| 406 | 405 | ||
| 407 | /* | 406 | /* |
| 408 | * Initialize TX Info descriptor | 407 | * Initialize TXWI descriptor |
| 409 | */ | 408 | */ |
| 410 | rt2x00_desc_read(txwi, 0, &word); | 409 | rt2800_write_txwi(skb, txdesc); |
| 411 | rt2x00_set_field32(&word, TXWI_W0_FRAG, | ||
| 412 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | ||
| 413 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); | ||
| 414 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); | ||
| 415 | rt2x00_set_field32(&word, TXWI_W0_TS, | ||
| 416 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | ||
| 417 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, | ||
| 418 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); | ||
| 419 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); | ||
| 420 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs); | ||
| 421 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); | ||
| 422 | rt2x00_set_field32(&word, TXWI_W0_BW, | ||
| 423 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); | ||
| 424 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, | ||
| 425 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); | ||
| 426 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); | ||
| 427 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); | ||
| 428 | rt2x00_desc_write(txwi, 0, word); | ||
| 429 | |||
| 430 | rt2x00_desc_read(txwi, 1, &word); | ||
| 431 | rt2x00_set_field32(&word, TXWI_W1_ACK, | ||
| 432 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); | ||
| 433 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, | ||
| 434 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | ||
| 435 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); | ||
| 436 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, | ||
| 437 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | ||
| 438 | txdesc->key_idx : 0xff); | ||
| 439 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | ||
| 440 | txdesc->length); | ||
| 441 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, | ||
| 442 | skbdesc->entry->queue->qid + 1); | ||
| 443 | rt2x00_desc_write(txwi, 1, word); | ||
| 444 | 410 | ||
| 445 | /* | 411 | /* |
| 446 | * Always write 0 to IV/EIV fields, hardware will insert the IV | 412 | * Initialize TXINFO descriptor |
| 447 | * from the IVEIV register when TXINFO_W0_WIV is set to 0. | ||
| 448 | * When TXINFO_W0_WIV is set to 1 it will use the IV data | ||
| 449 | * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which | ||
| 450 | * crypto entry in the registers should be used to encrypt the frame. | ||
| 451 | */ | ||
| 452 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | ||
| 453 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | ||
| 454 | |||
| 455 | /* | ||
| 456 | * Initialize TX descriptor | ||
| 457 | */ | 413 | */ |
| 458 | rt2x00_desc_read(txi, 0, &word); | 414 | rt2x00_desc_read(txi, 0, &word); |
| 459 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, | 415 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, |
| @@ -471,21 +427,14 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
| 471 | /* | 427 | /* |
| 472 | * TX data initialization | 428 | * TX data initialization |
| 473 | */ | 429 | */ |
| 474 | static void rt2800usb_write_beacon(struct queue_entry *entry) | 430 | static void rt2800usb_write_beacon(struct queue_entry *entry, |
| 431 | struct txentry_desc *txdesc) | ||
| 475 | { | 432 | { |
| 476 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 433 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| 477 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
| 478 | unsigned int beacon_base; | 434 | unsigned int beacon_base; |
| 479 | u32 reg; | 435 | u32 reg; |
| 480 | 436 | ||
| 481 | /* | 437 | /* |
| 482 | * Add the descriptor in front of the skb. | ||
| 483 | */ | ||
| 484 | skb_push(entry->skb, entry->queue->desc_size); | ||
| 485 | memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); | ||
| 486 | skbdesc->desc = entry->skb->data; | ||
| 487 | |||
| 488 | /* | ||
| 489 | * Disable beaconing while we are reloading the beacon data, | 438 | * Disable beaconing while we are reloading the beacon data, |
| 490 | * otherwise we might be sending out invalid data. | 439 | * otherwise we might be sending out invalid data. |
| 491 | */ | 440 | */ |
| @@ -494,6 +443,12 @@ static void rt2800usb_write_beacon(struct queue_entry *entry) | |||
| 494 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 443 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
| 495 | 444 | ||
| 496 | /* | 445 | /* |
| 446 | * Add the TXWI for the beacon to the skb. | ||
| 447 | */ | ||
| 448 | rt2800_write_txwi(entry->skb, txdesc); | ||
| 449 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
| 450 | |||
| 451 | /* | ||
| 497 | * Write entire beacon with descriptor to register. | 452 | * Write entire beacon with descriptor to register. |
| 498 | */ | 453 | */ |
| 499 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 454 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
| @@ -503,6 +458,14 @@ static void rt2800usb_write_beacon(struct queue_entry *entry) | |||
| 503 | REGISTER_TIMEOUT32(entry->skb->len)); | 458 | REGISTER_TIMEOUT32(entry->skb->len)); |
| 504 | 459 | ||
| 505 | /* | 460 | /* |
| 461 | * Enable beaconing again. | ||
| 462 | */ | ||
| 463 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
| 464 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
| 465 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
| 466 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
| 467 | |||
| 468 | /* | ||
| 506 | * Clean up the beacon skb. | 469 | * Clean up the beacon skb. |
| 507 | */ | 470 | */ |
| 508 | dev_kfree_skb(entry->skb); | 471 | dev_kfree_skb(entry->skb); |
| @@ -524,84 +487,53 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | |||
| 524 | return length; | 487 | return length; |
| 525 | } | 488 | } |
| 526 | 489 | ||
| 527 | static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
| 528 | const enum data_queue_qid queue) | ||
| 529 | { | ||
| 530 | u32 reg; | ||
| 531 | |||
| 532 | if (queue != QID_BEACON) { | ||
| 533 | rt2x00usb_kick_tx_queue(rt2x00dev, queue); | ||
| 534 | return; | ||
| 535 | } | ||
| 536 | |||
| 537 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
| 538 | if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) { | ||
| 539 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
| 540 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
| 541 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
| 542 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
| 543 | } | ||
| 544 | } | ||
| 545 | |||
| 546 | /* | 490 | /* |
| 547 | * RX control handlers | 491 | * RX control handlers |
| 548 | */ | 492 | */ |
| 549 | static void rt2800usb_fill_rxdone(struct queue_entry *entry, | 493 | static void rt2800usb_fill_rxdone(struct queue_entry *entry, |
| 550 | struct rxdone_entry_desc *rxdesc) | 494 | struct rxdone_entry_desc *rxdesc) |
| 551 | { | 495 | { |
| 552 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
| 553 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 496 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 554 | __le32 *rxi = (__le32 *)entry->skb->data; | 497 | __le32 *rxi = (__le32 *)entry->skb->data; |
| 555 | __le32 *rxwi; | ||
| 556 | __le32 *rxd; | 498 | __le32 *rxd; |
| 557 | u32 rxi0; | 499 | u32 word; |
| 558 | u32 rxwi0; | ||
| 559 | u32 rxwi1; | ||
| 560 | u32 rxwi2; | ||
| 561 | u32 rxwi3; | ||
| 562 | u32 rxd0; | ||
| 563 | int rx_pkt_len; | 500 | int rx_pkt_len; |
| 564 | 501 | ||
| 565 | /* | 502 | /* |
| 503 | * Copy descriptor to the skbdesc->desc buffer, making it safe from | ||
| 504 | * moving of frame data in rt2x00usb. | ||
| 505 | */ | ||
| 506 | memcpy(skbdesc->desc, rxi, skbdesc->desc_len); | ||
| 507 | |||
| 508 | /* | ||
| 566 | * RX frame format is : | 509 | * RX frame format is : |
| 567 | * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad | | 510 | * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad | |
| 568 | * |<------------ rx_pkt_len -------------->| | 511 | * |<------------ rx_pkt_len -------------->| |
| 569 | */ | 512 | */ |
| 570 | rt2x00_desc_read(rxi, 0, &rxi0); | 513 | rt2x00_desc_read(rxi, 0, &word); |
| 571 | rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN); | 514 | rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN); |
| 572 | |||
| 573 | rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE); | ||
| 574 | 515 | ||
| 575 | /* | 516 | /* |
| 576 | * FIXME : we need to check for rx_pkt_len validity | 517 | * Remove the RXINFO structure from the sbk. |
| 577 | */ | 518 | */ |
| 578 | rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len); | 519 | skb_pull(entry->skb, RXINFO_DESC_SIZE); |
| 579 | 520 | ||
| 580 | /* | 521 | /* |
| 581 | * Copy descriptor to the skbdesc->desc buffer, making it safe from | 522 | * FIXME: we need to check for rx_pkt_len validity |
| 582 | * moving of frame data in rt2x00usb. | ||
| 583 | */ | 523 | */ |
| 584 | memcpy(skbdesc->desc, rxi, skbdesc->desc_len); | 524 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); |
| 585 | 525 | ||
| 586 | /* | 526 | /* |
| 587 | * It is now safe to read the descriptor on all architectures. | 527 | * It is now safe to read the descriptor on all architectures. |
| 588 | */ | 528 | */ |
| 589 | rt2x00_desc_read(rxwi, 0, &rxwi0); | 529 | rt2x00_desc_read(rxd, 0, &word); |
| 590 | rt2x00_desc_read(rxwi, 1, &rxwi1); | ||
| 591 | rt2x00_desc_read(rxwi, 2, &rxwi2); | ||
| 592 | rt2x00_desc_read(rxwi, 3, &rxwi3); | ||
| 593 | rt2x00_desc_read(rxd, 0, &rxd0); | ||
| 594 | 530 | ||
| 595 | if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR)) | 531 | if (rt2x00_get_field32(word, RXD_W0_CRC_ERROR)) |
| 596 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 532 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
| 597 | 533 | ||
| 598 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 534 | rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W0_CIPHER_ERROR); |
| 599 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); | ||
| 600 | rxdesc->cipher_status = | ||
| 601 | rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR); | ||
| 602 | } | ||
| 603 | 535 | ||
| 604 | if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) { | 536 | if (rt2x00_get_field32(word, RXD_W0_DECRYPTED)) { |
| 605 | /* | 537 | /* |
| 606 | * Hardware has stripped IV/EIV data from 802.11 frame during | 538 | * Hardware has stripped IV/EIV data from 802.11 frame during |
| 607 | * decryption. Unfortunately the descriptor doesn't contain | 539 | * decryption. Unfortunately the descriptor doesn't contain |
| @@ -616,41 +548,21 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
| 616 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | 548 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; |
| 617 | } | 549 | } |
| 618 | 550 | ||
| 619 | if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS)) | 551 | if (rt2x00_get_field32(word, RXD_W0_MY_BSS)) |
| 620 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 552 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
| 621 | 553 | ||
| 622 | if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) | 554 | if (rt2x00_get_field32(word, RXD_W0_L2PAD)) |
| 623 | rxdesc->dev_flags |= RXDONE_L2PAD; | 555 | rxdesc->dev_flags |= RXDONE_L2PAD; |
| 624 | 556 | ||
| 625 | if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) | ||
| 626 | rxdesc->flags |= RX_FLAG_SHORT_GI; | ||
| 627 | |||
| 628 | if (rt2x00_get_field32(rxwi1, RXWI_W1_BW)) | ||
| 629 | rxdesc->flags |= RX_FLAG_40MHZ; | ||
| 630 | |||
| 631 | /* | 557 | /* |
| 632 | * Detect RX rate, always use MCS as signal type. | 558 | * Remove RXD descriptor from end of buffer. |
| 633 | */ | 559 | */ |
| 634 | rxdesc->dev_flags |= RXDONE_SIGNAL_MCS; | 560 | skb_trim(entry->skb, rx_pkt_len); |
| 635 | rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE); | ||
| 636 | rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS); | ||
| 637 | |||
| 638 | /* | ||
| 639 | * Mask of 0x8 bit to remove the short preamble flag. | ||
| 640 | */ | ||
| 641 | if (rxdesc->rate_mode == RATE_MODE_CCK) | ||
| 642 | rxdesc->signal &= ~0x8; | ||
| 643 | |||
| 644 | rxdesc->rssi = | ||
| 645 | (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + | ||
| 646 | rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; | ||
| 647 | |||
| 648 | rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); | ||
| 649 | 561 | ||
| 650 | /* | 562 | /* |
| 651 | * Remove RXWI descriptor from start of buffer. | 563 | * Process the RXWI structure. |
| 652 | */ | 564 | */ |
| 653 | skb_pull(entry->skb, skbdesc->desc_len); | 565 | rt2800_process_rxwi(entry->skb, rxdesc); |
| 654 | } | 566 | } |
| 655 | 567 | ||
| 656 | /* | 568 | /* |
| @@ -743,7 +655,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
| 743 | .write_tx_data = rt2x00usb_write_tx_data, | 655 | .write_tx_data = rt2x00usb_write_tx_data, |
| 744 | .write_beacon = rt2800usb_write_beacon, | 656 | .write_beacon = rt2800usb_write_beacon, |
| 745 | .get_tx_data_len = rt2800usb_get_tx_data_len, | 657 | .get_tx_data_len = rt2800usb_get_tx_data_len, |
| 746 | .kick_tx_queue = rt2800usb_kick_tx_queue, | 658 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
| 747 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 659 | .kill_tx_queue = rt2x00usb_kill_tx_queue, |
| 748 | .fill_rxdone = rt2800usb_fill_rxdone, | 660 | .fill_rxdone = rt2800usb_fill_rxdone, |
| 749 | .config_shared_key = rt2800_config_shared_key, | 661 | .config_shared_key = rt2800_config_shared_key, |
| @@ -841,7 +753,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
| 841 | { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, | 753 | { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 842 | { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, | 754 | { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 843 | /* EnGenius */ | 755 | /* EnGenius */ |
| 844 | { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, | 756 | { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 845 | { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, | 757 | { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, |
| 846 | /* Gigabyte */ | 758 | /* Gigabyte */ |
| 847 | { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 759 | { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, |
