diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-05-11 14:24:55 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-11 14:24:55 -0400 |
commit | cc755896a4274f11283bca32d1d658203844057a (patch) | |
tree | 218970ece71df99f686b9416b7fd88b921690ebb /drivers/net/wireless/rt2x00/rt2800usb.c | |
parent | d250fe91ae129bff0968e685cc9c466d3a5e3482 (diff) | |
parent | 9459d59fbf0bc82ff4c804679fa8bc22788eca63 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/ath/ar9170/main.c
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 e3f3a97db80..8ad0669a1b9 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) }, |