diff options
author | Gertjan van Wingerde <gwingerde@kpnplanet.nl> | 2008-06-16 13:56:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-26 16:49:16 -0400 |
commit | c4da004857056e6ee034c4110ccdcba659077b7e (patch) | |
tree | 641f8d9ddab7b8b6ba41fefc57a517abce15e8e6 /drivers/net | |
parent | 30caa6e3d586442f7c3ad081260ee1b22bb123de (diff) |
rt2x00: Replace statically allocated DMA buffers with mapped skb's.
The current PCI drivers require a lot of pre-allocated DMA buffers. Reduce this
by using dynamically mapped skb's (using pci_map_single) instead of the pre-
allocated DMA buffers that are allocated at device start-up time.
At the same time move common RX path code into rt2x00lib from rt2x00pci and
rt2x00usb, as the RX paths now are now almost the same.
Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 28 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 64 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 125 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 85 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 9 |
10 files changed, 204 insertions, 176 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 76ec1514fa44..de2dd336f23d 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -632,15 +632,15 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | |||
632 | struct queue_entry *entry) | 632 | struct queue_entry *entry) |
633 | { | 633 | { |
634 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 634 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
635 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
635 | u32 word; | 636 | u32 word; |
636 | 637 | ||
637 | rt2x00_desc_read(entry_priv->desc, 2, &word); | 638 | rt2x00_desc_read(entry_priv->desc, 2, &word); |
638 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, | 639 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); |
639 | entry->queue->data_size); | ||
640 | rt2x00_desc_write(entry_priv->desc, 2, word); | 640 | rt2x00_desc_write(entry_priv->desc, 2, word); |
641 | 641 | ||
642 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 642 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
643 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 643 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
644 | rt2x00_desc_write(entry_priv->desc, 1, word); | 644 | rt2x00_desc_write(entry_priv->desc, 1, word); |
645 | 645 | ||
646 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 646 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
@@ -1012,7 +1012,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1012 | * Start writing the descriptor words. | 1012 | * Start writing the descriptor words. |
1013 | */ | 1013 | */ |
1014 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1014 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
1016 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1016 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1017 | 1017 | ||
1018 | rt2x00_desc_read(txd, 2, &word); | 1018 | rt2x00_desc_read(txd, 2, &word); |
@@ -1412,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1412 | rt2400pci_probe_hw_mode(rt2x00dev); | 1412 | rt2400pci_probe_hw_mode(rt2x00dev); |
1413 | 1413 | ||
1414 | /* | 1414 | /* |
1415 | * This device requires the atim queue | 1415 | * This device requires the atim queue and DMA-mapped skbs. |
1416 | */ | 1416 | */ |
1417 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1417 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1418 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
1418 | 1419 | ||
1419 | /* | 1420 | /* |
1420 | * Set the rssi offset. | 1421 | * Set the rssi offset. |
@@ -1526,7 +1527,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1526 | * Write entire beacon with descriptor to register, | 1527 | * Write entire beacon with descriptor to register, |
1527 | * and kick the beacon generator. | 1528 | * and kick the beacon generator. |
1528 | */ | 1529 | */ |
1529 | memcpy(entry_priv->data, skb->data, skb->len); | 1530 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); |
1530 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | 1531 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); |
1531 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | 1532 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); |
1532 | 1533 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5f0117f9a88b..5077b62dcc5a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -727,10 +727,11 @@ static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | |||
727 | struct queue_entry *entry) | 727 | struct queue_entry *entry) |
728 | { | 728 | { |
729 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 729 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
730 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
730 | u32 word; | 731 | u32 word; |
731 | 732 | ||
732 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 733 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
733 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 734 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
734 | rt2x00_desc_write(entry_priv->desc, 1, word); | 735 | rt2x00_desc_write(entry_priv->desc, 1, word); |
735 | 736 | ||
736 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 737 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
@@ -1171,7 +1172,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1171 | * Start writing the descriptor words. | 1172 | * Start writing the descriptor words. |
1172 | */ | 1173 | */ |
1173 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1174 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
1174 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 1175 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
1175 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1176 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1176 | 1177 | ||
1177 | rt2x00_desc_read(txd, 2, &word); | 1178 | rt2x00_desc_read(txd, 2, &word); |
@@ -1752,9 +1753,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1752 | rt2500pci_probe_hw_mode(rt2x00dev); | 1753 | rt2500pci_probe_hw_mode(rt2x00dev); |
1753 | 1754 | ||
1754 | /* | 1755 | /* |
1755 | * This device requires the atim queue | 1756 | * This device requires the atim queue and DMA-mapped skbs. |
1756 | */ | 1757 | */ |
1757 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1758 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1759 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
1758 | 1760 | ||
1759 | /* | 1761 | /* |
1760 | * Set the rssi offset. | 1762 | * Set the rssi offset. |
@@ -1842,7 +1844,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1842 | * Write entire beacon with descriptor to register, | 1844 | * Write entire beacon with descriptor to register, |
1843 | * and kick the beacon generator. | 1845 | * and kick the beacon generator. |
1844 | */ | 1846 | */ |
1845 | memcpy(entry_priv->data, skb->data, skb->len); | 1847 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); |
1846 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | 1848 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); |
1847 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | 1849 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); |
1848 | 1850 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 08e8b0a005a6..28c9026bb568 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -601,6 +601,7 @@ enum rt2x00_flags { | |||
601 | DRIVER_REQUIRE_BEACON_GUARD, | 601 | DRIVER_REQUIRE_BEACON_GUARD, |
602 | DRIVER_REQUIRE_ATIM_QUEUE, | 602 | DRIVER_REQUIRE_ATIM_QUEUE, |
603 | DRIVER_REQUIRE_SCHEDULED, | 603 | DRIVER_REQUIRE_SCHEDULED, |
604 | DRIVER_REQUIRE_DMA, | ||
604 | 605 | ||
605 | /* | 606 | /* |
606 | * Driver configuration | 607 | * Driver configuration |
@@ -899,16 +900,33 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
899 | } | 900 | } |
900 | 901 | ||
901 | /** | 902 | /** |
902 | * rt2x00queue_alloc_skb - allocate a skb. | 903 | * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. |
904 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
903 | * @queue: The queue for which the skb will be applicable. | 905 | * @queue: The queue for which the skb will be applicable. |
904 | */ | 906 | */ |
905 | struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue); | 907 | struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, |
908 | struct queue_entry *entry); | ||
909 | |||
910 | /** | ||
911 | * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. | ||
912 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
913 | * @skb: The skb to map. | ||
914 | */ | ||
915 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
916 | |||
917 | /** | ||
918 | * rt2x00queue_unmap_skb - Unmap a skb from DMA. | ||
919 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
920 | * @skb: The skb to unmap. | ||
921 | */ | ||
922 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
906 | 923 | ||
907 | /** | 924 | /** |
908 | * rt2x00queue_free_skb - free a skb | 925 | * rt2x00queue_free_skb - free a skb |
926 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
909 | * @skb: The skb to free. | 927 | * @skb: The skb to free. |
910 | */ | 928 | */ |
911 | void rt2x00queue_free_skb(struct sk_buff *skb); | 929 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); |
912 | 930 | ||
913 | /** | 931 | /** |
914 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input | 932 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input |
@@ -977,8 +995,8 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | |||
977 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 995 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
978 | void rt2x00lib_txdone(struct queue_entry *entry, | 996 | void rt2x00lib_txdone(struct queue_entry *entry, |
979 | struct txdone_entry_desc *txdesc); | 997 | struct txdone_entry_desc *txdesc); |
980 | void rt2x00lib_rxdone(struct queue_entry *entry, | 998 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, |
981 | struct rxdone_entry_desc *rxdesc); | 999 | struct queue_entry *entry); |
982 | 1000 | ||
983 | /* | 1001 | /* |
984 | * mac80211 handlers. | 1002 | * mac80211 handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b8e0c4c3ed0a..99b14ba99d97 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -468,6 +468,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) | |||
468 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, | 468 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
469 | struct ieee80211_vif *vif) | 469 | struct ieee80211_vif *vif) |
470 | { | 470 | { |
471 | struct rt2x00_dev *rt2x00dev = data; | ||
471 | struct rt2x00_intf *intf = vif_to_intf(vif); | 472 | struct rt2x00_intf *intf = vif_to_intf(vif); |
472 | 473 | ||
473 | if (vif->type != IEEE80211_IF_TYPE_AP && | 474 | if (vif->type != IEEE80211_IF_TYPE_AP && |
@@ -477,7 +478,7 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac, | |||
477 | /* | 478 | /* |
478 | * Clean up the beacon skb. | 479 | * Clean up the beacon skb. |
479 | */ | 480 | */ |
480 | dev_kfree_skb_irq(intf->beacon->skb); | 481 | rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb); |
481 | intf->beacon->skb = NULL; | 482 | intf->beacon->skb = NULL; |
482 | 483 | ||
483 | spin_lock(&intf->lock); | 484 | spin_lock(&intf->lock); |
@@ -555,34 +556,55 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
555 | } | 556 | } |
556 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 557 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
557 | 558 | ||
558 | void rt2x00lib_rxdone(struct queue_entry *entry, | 559 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, |
559 | struct rxdone_entry_desc *rxdesc) | 560 | struct queue_entry *entry) |
560 | { | 561 | { |
561 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 562 | struct rxdone_entry_desc rxdesc; |
563 | struct sk_buff *skb; | ||
562 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 564 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
563 | unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
564 | struct ieee80211_supported_band *sband; | 565 | struct ieee80211_supported_band *sband; |
565 | struct ieee80211_hdr *hdr; | 566 | struct ieee80211_hdr *hdr; |
566 | const struct rt2x00_rate *rate; | 567 | const struct rt2x00_rate *rate; |
568 | unsigned int header_size; | ||
567 | unsigned int align; | 569 | unsigned int align; |
568 | unsigned int i; | 570 | unsigned int i; |
569 | int idx = -1; | 571 | int idx = -1; |
570 | 572 | ||
571 | /* | 573 | /* |
574 | * Allocate a new sk_buffer. If no new buffer available, drop the | ||
575 | * received frame and reuse the existing buffer. | ||
576 | */ | ||
577 | skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); | ||
578 | if (!skb) | ||
579 | return; | ||
580 | |||
581 | /* | ||
582 | * Unmap the skb. | ||
583 | */ | ||
584 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | ||
585 | |||
586 | /* | ||
587 | * Extract the RXD details. | ||
588 | */ | ||
589 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
590 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
591 | |||
592 | /* | ||
572 | * The data behind the ieee80211 header must be | 593 | * The data behind the ieee80211 header must be |
573 | * aligned on a 4 byte boundary. | 594 | * aligned on a 4 byte boundary. |
574 | */ | 595 | */ |
596 | header_size = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
575 | align = ((unsigned long)(entry->skb->data + header_size)) & 3; | 597 | align = ((unsigned long)(entry->skb->data + header_size)) & 3; |
576 | 598 | ||
577 | if (align) { | 599 | if (align) { |
578 | skb_push(entry->skb, align); | 600 | skb_push(entry->skb, align); |
579 | /* Move entire frame in 1 command */ | 601 | /* Move entire frame in 1 command */ |
580 | memmove(entry->skb->data, entry->skb->data + align, | 602 | memmove(entry->skb->data, entry->skb->data + align, |
581 | rxdesc->size); | 603 | rxdesc.size); |
582 | } | 604 | } |
583 | 605 | ||
584 | /* Update data pointers, trim buffer to correct size */ | 606 | /* Update data pointers, trim buffer to correct size */ |
585 | skb_trim(entry->skb, rxdesc->size); | 607 | skb_trim(entry->skb, rxdesc.size); |
586 | 608 | ||
587 | /* | 609 | /* |
588 | * Update RX statistics. | 610 | * Update RX statistics. |
@@ -591,10 +613,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
591 | for (i = 0; i < sband->n_bitrates; i++) { | 613 | for (i = 0; i < sband->n_bitrates; i++) { |
592 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); | 614 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
593 | 615 | ||
594 | if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && | 616 | if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && |
595 | (rate->plcp == rxdesc->signal)) || | 617 | (rate->plcp == rxdesc.signal)) || |
596 | (!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && | 618 | (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && |
597 | (rate->bitrate == rxdesc->signal))) { | 619 | (rate->bitrate == rxdesc.signal))) { |
598 | idx = i; | 620 | idx = i; |
599 | break; | 621 | break; |
600 | } | 622 | } |
@@ -602,8 +624,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
602 | 624 | ||
603 | if (idx < 0) { | 625 | if (idx < 0) { |
604 | WARNING(rt2x00dev, "Frame received with unrecognized signal," | 626 | WARNING(rt2x00dev, "Frame received with unrecognized signal," |
605 | "signal=0x%.2x, plcp=%d.\n", rxdesc->signal, | 627 | "signal=0x%.2x, plcp=%d.\n", rxdesc.signal, |
606 | !!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP)); | 628 | !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP)); |
607 | idx = 0; | 629 | idx = 0; |
608 | } | 630 | } |
609 | 631 | ||
@@ -612,16 +634,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
612 | */ | 634 | */ |
613 | hdr = (struct ieee80211_hdr *)entry->skb->data; | 635 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
614 | if (ieee80211_is_beacon(hdr->frame_control) && | 636 | if (ieee80211_is_beacon(hdr->frame_control) && |
615 | (rxdesc->dev_flags & RXDONE_MY_BSS)) | 637 | (rxdesc.dev_flags & RXDONE_MY_BSS)) |
616 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); | 638 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi); |
617 | 639 | ||
618 | rt2x00dev->link.qual.rx_success++; | 640 | rt2x00dev->link.qual.rx_success++; |
619 | 641 | ||
620 | rx_status->rate_idx = idx; | 642 | rx_status->rate_idx = idx; |
621 | rx_status->qual = | 643 | rx_status->qual = |
622 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); | 644 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi); |
623 | rx_status->signal = rxdesc->rssi; | 645 | rx_status->signal = rxdesc.rssi; |
624 | rx_status->flag = rxdesc->flags; | 646 | rx_status->flag = rxdesc.flags; |
625 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 647 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
626 | 648 | ||
627 | /* | 649 | /* |
@@ -630,7 +652,11 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
630 | */ | 652 | */ |
631 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); | 653 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); |
632 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); | 654 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
633 | entry->skb = NULL; | 655 | |
656 | /* | ||
657 | * Replace the skb with the freshly allocated one. | ||
658 | */ | ||
659 | entry->skb = skb; | ||
634 | } | 660 | } |
635 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 661 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
636 | 662 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index e7e3a459b66a..f9d0d76f8706 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -65,7 +65,7 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry) | |||
65 | skbdesc->desc_len = entry->queue->desc_size; | 65 | skbdesc->desc_len = entry->queue->desc_size; |
66 | skbdesc->entry = entry; | 66 | skbdesc->entry = entry; |
67 | 67 | ||
68 | memcpy(entry_priv->data, entry->skb->data, entry->skb->len); | 68 | rt2x00queue_map_txskb(entry->queue->rt2x00dev, entry->skb); |
69 | 69 | ||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
@@ -74,59 +74,12 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | |||
74 | /* | 74 | /* |
75 | * TX/RX data handlers. | 75 | * TX/RX data handlers. |
76 | */ | 76 | */ |
77 | static void rt2x00pci_rxdone_entry(struct rt2x00_dev *rt2x00dev, | ||
78 | struct queue_entry *entry) | ||
79 | { | ||
80 | struct sk_buff *skb; | ||
81 | struct skb_frame_desc *skbdesc; | ||
82 | struct rxdone_entry_desc rxdesc; | ||
83 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
84 | |||
85 | /* | ||
86 | * Allocate a new sk_buffer. If no new buffer available, drop the | ||
87 | * received frame and reuse the existing buffer. | ||
88 | */ | ||
89 | skb = rt2x00queue_alloc_skb(entry->queue); | ||
90 | if (!skb) | ||
91 | return; | ||
92 | |||
93 | /* | ||
94 | * Extract the RXD details. | ||
95 | */ | ||
96 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
97 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
98 | |||
99 | /* | ||
100 | * Copy the received data to the entries' skb. | ||
101 | */ | ||
102 | memcpy(entry->skb->data, entry_priv->data, rxdesc.size); | ||
103 | skb_trim(entry->skb, rxdesc.size); | ||
104 | |||
105 | /* | ||
106 | * Fill in skb descriptor | ||
107 | */ | ||
108 | skbdesc = get_skb_frame_desc(entry->skb); | ||
109 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
110 | skbdesc->desc = entry_priv->desc; | ||
111 | skbdesc->desc_len = entry->queue->desc_size; | ||
112 | skbdesc->entry = entry; | ||
113 | |||
114 | /* | ||
115 | * Send the frame to rt2x00lib for further processing. | ||
116 | */ | ||
117 | rt2x00lib_rxdone(entry, &rxdesc); | ||
118 | |||
119 | /* | ||
120 | * Replace the entries' skb with the newly allocated one. | ||
121 | */ | ||
122 | entry->skb = skb; | ||
123 | } | ||
124 | |||
125 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 77 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) |
126 | { | 78 | { |
127 | struct data_queue *queue = rt2x00dev->rx; | 79 | struct data_queue *queue = rt2x00dev->rx; |
128 | struct queue_entry *entry; | 80 | struct queue_entry *entry; |
129 | struct queue_entry_priv_pci *entry_priv; | 81 | struct queue_entry_priv_pci *entry_priv; |
82 | struct skb_frame_desc *skbdesc; | ||
130 | u32 word; | 83 | u32 word; |
131 | 84 | ||
132 | while (1) { | 85 | while (1) { |
@@ -137,12 +90,22 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
137 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 90 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
138 | break; | 91 | break; |
139 | 92 | ||
140 | rt2x00pci_rxdone_entry(rt2x00dev, entry); | 93 | /* |
94 | * Fill in desc fields of the skb descriptor | ||
95 | */ | ||
96 | skbdesc = get_skb_frame_desc(entry->skb); | ||
97 | skbdesc->desc = entry_priv->desc; | ||
98 | skbdesc->desc_len = entry->queue->desc_size; | ||
99 | |||
100 | /* | ||
101 | * Send the frame to rt2x00lib for further processing. | ||
102 | */ | ||
103 | rt2x00lib_rxdone(rt2x00dev, entry); | ||
141 | 104 | ||
142 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { | 105 | /* |
143 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | 106 | * Reset the RXD for this entry. |
144 | rt2x00_desc_write(entry_priv->desc, 0, word); | 107 | */ |
145 | } | 108 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); |
146 | 109 | ||
147 | rt2x00queue_index_inc(queue, Q_INDEX); | 110 | rt2x00queue_index_inc(queue, Q_INDEX); |
148 | } | 111 | } |
@@ -156,6 +119,11 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | |||
156 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | 119 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); |
157 | u32 word; | 120 | u32 word; |
158 | 121 | ||
122 | /* | ||
123 | * Unmap the skb. | ||
124 | */ | ||
125 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | ||
126 | |||
159 | rt2x00lib_txdone(entry, txdesc); | 127 | rt2x00lib_txdone(entry, txdesc); |
160 | 128 | ||
161 | /* | 129 | /* |
@@ -185,33 +153,6 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | |||
185 | /* | 153 | /* |
186 | * Device initialization handlers. | 154 | * Device initialization handlers. |
187 | */ | 155 | */ |
188 | #define desc_size(__queue) \ | ||
189 | ({ \ | ||
190 | ((__queue)->limit * (__queue)->desc_size);\ | ||
191 | }) | ||
192 | |||
193 | #define data_size(__queue) \ | ||
194 | ({ \ | ||
195 | ((__queue)->limit * (__queue)->data_size);\ | ||
196 | }) | ||
197 | |||
198 | #define dma_size(__queue) \ | ||
199 | ({ \ | ||
200 | data_size(__queue) + desc_size(__queue);\ | ||
201 | }) | ||
202 | |||
203 | #define desc_offset(__queue, __base, __i) \ | ||
204 | ({ \ | ||
205 | (__base) + data_size(__queue) + \ | ||
206 | ((__i) * (__queue)->desc_size); \ | ||
207 | }) | ||
208 | |||
209 | #define data_offset(__queue, __base, __i) \ | ||
210 | ({ \ | ||
211 | (__base) + \ | ||
212 | ((__i) * (__queue)->data_size); \ | ||
213 | }) | ||
214 | |||
215 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | 156 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, |
216 | struct data_queue *queue) | 157 | struct data_queue *queue) |
217 | { | 158 | { |
@@ -223,22 +164,21 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
223 | /* | 164 | /* |
224 | * Allocate DMA memory for descriptor and buffer. | 165 | * Allocate DMA memory for descriptor and buffer. |
225 | */ | 166 | */ |
226 | addr = dma_alloc_coherent(rt2x00dev->dev, dma_size(queue), &dma, | 167 | addr = dma_alloc_coherent(rt2x00dev->dev, |
227 | GFP_KERNEL | GFP_DMA); | 168 | queue->limit * queue->desc_size, |
169 | &dma, GFP_KERNEL | GFP_DMA); | ||
228 | if (!addr) | 170 | if (!addr) |
229 | return -ENOMEM; | 171 | return -ENOMEM; |
230 | 172 | ||
231 | memset(addr, 0, dma_size(queue)); | 173 | memset(addr, 0, queue->limit * queue->desc_size); |
232 | 174 | ||
233 | /* | 175 | /* |
234 | * Initialize all queue entries to contain valid addresses. | 176 | * Initialize all queue entries to contain valid addresses. |
235 | */ | 177 | */ |
236 | for (i = 0; i < queue->limit; i++) { | 178 | for (i = 0; i < queue->limit; i++) { |
237 | entry_priv = queue->entries[i].priv_data; | 179 | entry_priv = queue->entries[i].priv_data; |
238 | entry_priv->desc = desc_offset(queue, addr, i); | 180 | entry_priv->desc = addr + i * queue->desc_size; |
239 | entry_priv->desc_dma = desc_offset(queue, dma, i); | 181 | entry_priv->desc_dma = dma + i * queue->desc_size; |
240 | entry_priv->data = data_offset(queue, addr, i); | ||
241 | entry_priv->data_dma = data_offset(queue, dma, i); | ||
242 | } | 182 | } |
243 | 183 | ||
244 | return 0; | 184 | return 0; |
@@ -250,10 +190,11 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
250 | struct queue_entry_priv_pci *entry_priv = | 190 | struct queue_entry_priv_pci *entry_priv = |
251 | queue->entries[0].priv_data; | 191 | queue->entries[0].priv_data; |
252 | 192 | ||
253 | if (entry_priv->data) | 193 | if (entry_priv->desc) |
254 | dma_free_coherent(rt2x00dev->dev, dma_size(queue), | 194 | dma_free_coherent(rt2x00dev->dev, |
255 | entry_priv->data, entry_priv->data_dma); | 195 | queue->limit * queue->desc_size, |
256 | entry_priv->data = NULL; | 196 | entry_priv->desc, entry_priv->desc_dma); |
197 | entry_priv->desc = NULL; | ||
257 | } | 198 | } |
258 | 199 | ||
259 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 200 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 87c4a0cd78db..7e5708dca731 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -107,9 +107,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry); | |||
107 | struct queue_entry_priv_pci { | 107 | struct queue_entry_priv_pci { |
108 | __le32 *desc; | 108 | __le32 *desc; |
109 | dma_addr_t desc_dma; | 109 | dma_addr_t desc_dma; |
110 | |||
111 | void *data; | ||
112 | dma_addr_t data_dma; | ||
113 | }; | 110 | }; |
114 | 111 | ||
115 | /** | 112 | /** |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 278f1a1ac926..29d2b9128533 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -25,21 +25,24 @@ | |||
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/dma-mapping.h> | ||
28 | 29 | ||
29 | #include "rt2x00.h" | 30 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 31 | #include "rt2x00lib.h" |
31 | 32 | ||
32 | struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue) | 33 | struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, |
34 | struct queue_entry *entry) | ||
33 | { | 35 | { |
34 | struct sk_buff *skb; | ||
35 | unsigned int frame_size; | 36 | unsigned int frame_size; |
36 | unsigned int reserved_size; | 37 | unsigned int reserved_size; |
38 | struct sk_buff *skb; | ||
39 | struct skb_frame_desc *skbdesc; | ||
37 | 40 | ||
38 | /* | 41 | /* |
39 | * The frame size includes descriptor size, because the | 42 | * The frame size includes descriptor size, because the |
40 | * hardware directly receive the frame into the skbuffer. | 43 | * hardware directly receive the frame into the skbuffer. |
41 | */ | 44 | */ |
42 | frame_size = queue->data_size + queue->desc_size; | 45 | frame_size = entry->queue->data_size + entry->queue->desc_size; |
43 | 46 | ||
44 | /* | 47 | /* |
45 | * Reserve a few bytes extra headroom to allow drivers some moving | 48 | * Reserve a few bytes extra headroom to allow drivers some moving |
@@ -57,12 +60,67 @@ struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue) | |||
57 | skb_reserve(skb, reserved_size); | 60 | skb_reserve(skb, reserved_size); |
58 | skb_put(skb, frame_size); | 61 | skb_put(skb, frame_size); |
59 | 62 | ||
63 | /* | ||
64 | * Populate skbdesc. | ||
65 | */ | ||
66 | skbdesc = get_skb_frame_desc(skb); | ||
67 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
68 | skbdesc->entry = entry; | ||
69 | |||
70 | if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) { | ||
71 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, | ||
72 | skb->data, | ||
73 | skb->len, | ||
74 | DMA_FROM_DEVICE); | ||
75 | skbdesc->flags |= SKBDESC_DMA_MAPPED_RX; | ||
76 | } | ||
77 | |||
60 | return skb; | 78 | return skb; |
61 | } | 79 | } |
62 | EXPORT_SYMBOL_GPL(rt2x00queue_alloc_skb); | 80 | EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); |
63 | 81 | ||
64 | void rt2x00queue_free_skb(struct sk_buff *skb) | 82 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) |
65 | { | 83 | { |
84 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
85 | |||
86 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, | ||
87 | DMA_TO_DEVICE); | ||
88 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | ||
89 | } | ||
90 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); | ||
91 | |||
92 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
93 | { | ||
94 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
95 | |||
96 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { | ||
97 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
98 | DMA_FROM_DEVICE); | ||
99 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; | ||
100 | } | ||
101 | |||
102 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { | ||
103 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
104 | DMA_TO_DEVICE); | ||
105 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; | ||
106 | } | ||
107 | } | ||
108 | EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); | ||
109 | |||
110 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
111 | { | ||
112 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
113 | |||
114 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { | ||
115 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
116 | DMA_FROM_DEVICE); | ||
117 | } | ||
118 | |||
119 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { | ||
120 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
121 | DMA_TO_DEVICE); | ||
122 | } | ||
123 | |||
66 | dev_kfree_skb_any(skb); | 124 | dev_kfree_skb_any(skb); |
67 | } | 125 | } |
68 | EXPORT_SYMBOL_GPL(rt2x00queue_free_skb); | 126 | EXPORT_SYMBOL_GPL(rt2x00queue_free_skb); |
@@ -421,7 +479,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
421 | return 0; | 479 | return 0; |
422 | } | 480 | } |
423 | 481 | ||
424 | static void rt2x00queue_free_skbs(struct data_queue *queue) | 482 | static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, |
483 | struct data_queue *queue) | ||
425 | { | 484 | { |
426 | unsigned int i; | 485 | unsigned int i; |
427 | 486 | ||
@@ -430,27 +489,27 @@ static void rt2x00queue_free_skbs(struct data_queue *queue) | |||
430 | 489 | ||
431 | for (i = 0; i < queue->limit; i++) { | 490 | for (i = 0; i < queue->limit; i++) { |
432 | if (queue->entries[i].skb) | 491 | if (queue->entries[i].skb) |
433 | rt2x00queue_free_skb(queue->entries[i].skb); | 492 | rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb); |
434 | } | 493 | } |
435 | } | 494 | } |
436 | 495 | ||
437 | static int rt2x00queue_alloc_skbs(struct data_queue *queue) | 496 | static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, |
497 | struct data_queue *queue) | ||
438 | { | 498 | { |
439 | unsigned int i; | 499 | unsigned int i; |
440 | struct sk_buff *skb; | 500 | struct sk_buff *skb; |
441 | 501 | ||
442 | for (i = 0; i < queue->limit; i++) { | 502 | for (i = 0; i < queue->limit; i++) { |
443 | skb = rt2x00queue_alloc_skb(queue); | 503 | skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); |
444 | if (!skb) | 504 | if (!skb) |
445 | goto exit; | 505 | goto exit; |
446 | |||
447 | queue->entries[i].skb = skb; | 506 | queue->entries[i].skb = skb; |
448 | } | 507 | } |
449 | 508 | ||
450 | return 0; | 509 | return 0; |
451 | 510 | ||
452 | exit: | 511 | exit: |
453 | rt2x00queue_free_skbs(queue); | 512 | rt2x00queue_free_skbs(rt2x00dev, queue); |
454 | 513 | ||
455 | return -ENOMEM; | 514 | return -ENOMEM; |
456 | } | 515 | } |
@@ -481,7 +540,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
481 | goto exit; | 540 | goto exit; |
482 | } | 541 | } |
483 | 542 | ||
484 | status = rt2x00queue_alloc_skbs(rt2x00dev->rx); | 543 | status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); |
485 | if (status) | 544 | if (status) |
486 | goto exit; | 545 | goto exit; |
487 | 546 | ||
@@ -499,7 +558,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
499 | { | 558 | { |
500 | struct data_queue *queue; | 559 | struct data_queue *queue; |
501 | 560 | ||
502 | rt2x00queue_free_skbs(rt2x00dev->rx); | 561 | rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); |
503 | 562 | ||
504 | queue_for_each(rt2x00dev, queue) { | 563 | queue_for_each(rt2x00dev, queue) { |
505 | kfree(queue->entries); | 564 | kfree(queue->entries); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index fcf52520b016..192b6e789a7f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -83,9 +83,10 @@ enum data_queue_qid { | |||
83 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc | 83 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc |
84 | * | 84 | * |
85 | */ | 85 | */ |
86 | //enum skb_frame_desc_flags { | 86 | enum skb_frame_desc_flags { |
87 | // TEMPORARILY EMPTY | 87 | SKBDESC_DMA_MAPPED_RX = (1 << 0), |
88 | //}; | 88 | SKBDESC_DMA_MAPPED_TX = (1 << 1), |
89 | }; | ||
89 | 90 | ||
90 | /** | 91 | /** |
91 | * struct skb_frame_desc: Descriptor information for the skb buffer | 92 | * struct skb_frame_desc: Descriptor information for the skb buffer |
@@ -94,19 +95,20 @@ enum data_queue_qid { | |||
94 | * this structure should not exceed the size of that array (40 bytes). | 95 | * this structure should not exceed the size of that array (40 bytes). |
95 | * | 96 | * |
96 | * @flags: Frame flags, see &enum skb_frame_desc_flags. | 97 | * @flags: Frame flags, see &enum skb_frame_desc_flags. |
97 | * @data: Pointer to data part of frame (Start of ieee80211 header). | 98 | * @desc_len: Length of the frame descriptor. |
98 | * @desc: Pointer to descriptor part of the frame. | 99 | * @desc: Pointer to descriptor part of the frame. |
99 | * Note that this pointer could point to something outside | 100 | * Note that this pointer could point to something outside |
100 | * of the scope of the skb->data pointer. | 101 | * of the scope of the skb->data pointer. |
101 | * @data_len: Length of the frame data. | 102 | * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. |
102 | * @desc_len: Length of the frame descriptor. | ||
103 | * @entry: The entry to which this sk buffer belongs. | 103 | * @entry: The entry to which this sk buffer belongs. |
104 | */ | 104 | */ |
105 | struct skb_frame_desc { | 105 | struct skb_frame_desc { |
106 | unsigned int flags; | 106 | unsigned int flags; |
107 | 107 | ||
108 | void *desc; | ||
109 | unsigned int desc_len; | 108 | unsigned int desc_len; |
109 | void *desc; | ||
110 | |||
111 | dma_addr_t skb_dma; | ||
110 | 112 | ||
111 | struct queue_entry *entry; | 113 | struct queue_entry *entry; |
112 | }; | 114 | }; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 29dba86c8cf0..552f0e94f800 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -266,9 +266,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
266 | { | 266 | { |
267 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 267 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
268 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 268 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
269 | struct sk_buff *skb; | 269 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
270 | struct skb_frame_desc *skbdesc; | ||
271 | struct rxdone_entry_desc rxdesc; | ||
272 | u8 rxd[32]; | 270 | u8 rxd[32]; |
273 | 271 | ||
274 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 272 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
@@ -284,36 +282,19 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
284 | goto skip_entry; | 282 | goto skip_entry; |
285 | 283 | ||
286 | /* | 284 | /* |
287 | * Fill in skb descriptor | 285 | * Fill in desc fields of the skb descriptor |
288 | */ | 286 | */ |
289 | skbdesc = get_skb_frame_desc(entry->skb); | ||
290 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
291 | skbdesc->entry = entry; | ||
292 | skbdesc->desc = rxd; | 287 | skbdesc->desc = rxd; |
293 | skbdesc->desc_len = entry->queue->desc_size; | 288 | skbdesc->desc_len = entry->queue->desc_size; |
294 | 289 | ||
295 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
296 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
297 | |||
298 | /* | ||
299 | * Allocate a new sk buffer to replace the current one. | ||
300 | * If allocation fails, we should drop the current frame | ||
301 | * so we can recycle the existing sk buffer for the new frame. | ||
302 | */ | ||
303 | skb = rt2x00queue_alloc_skb(entry->queue); | ||
304 | if (!skb) | ||
305 | goto skip_entry; | ||
306 | |||
307 | /* | 290 | /* |
308 | * Send the frame to rt2x00lib for further processing. | 291 | * Send the frame to rt2x00lib for further processing. |
309 | */ | 292 | */ |
310 | rt2x00lib_rxdone(entry, &rxdesc); | 293 | rt2x00lib_rxdone(rt2x00dev, entry); |
311 | 294 | ||
312 | /* | 295 | /* |
313 | * Replace current entry's skb with the newly allocated one, | 296 | * Reinitialize the urb. |
314 | * and reinitialize the urb. | ||
315 | */ | 297 | */ |
316 | entry->skb = skb; | ||
317 | urb->transfer_buffer = entry->skb->data; | 298 | urb->transfer_buffer = entry->skb->data; |
318 | urb->transfer_buffer_length = entry->skb->len; | 299 | urb->transfer_buffer_length = entry->skb->len; |
319 | 300 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 2a7f30620356..c9f6d4844139 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1030,11 +1030,12 @@ static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | |||
1030 | struct queue_entry *entry) | 1030 | struct queue_entry *entry) |
1031 | { | 1031 | { |
1032 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1032 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1033 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1033 | u32 word; | 1034 | u32 word; |
1034 | 1035 | ||
1035 | rt2x00_desc_read(entry_priv->desc, 5, &word); | 1036 | rt2x00_desc_read(entry_priv->desc, 5, &word); |
1036 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 1037 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1037 | entry_priv->data_dma); | 1038 | skbdesc->skb_dma); |
1038 | rt2x00_desc_write(entry_priv->desc, 5, word); | 1039 | rt2x00_desc_write(entry_priv->desc, 5, word); |
1039 | 1040 | ||
1040 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 1041 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
@@ -1522,7 +1523,6 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1522 | struct txentry_desc *txdesc) | 1523 | struct txentry_desc *txdesc) |
1523 | { | 1524 | { |
1524 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1525 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1525 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | ||
1526 | __le32 *txd = skbdesc->desc; | 1526 | __le32 *txd = skbdesc->desc; |
1527 | u32 word; | 1527 | u32 word; |
1528 | 1528 | ||
@@ -1557,7 +1557,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1557 | 1557 | ||
1558 | rt2x00_desc_read(txd, 6, &word); | 1558 | rt2x00_desc_read(txd, 6, &word); |
1559 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1559 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1560 | entry_priv->data_dma); | 1560 | skbdesc->skb_dma); |
1561 | rt2x00_desc_write(txd, 6, word); | 1561 | rt2x00_desc_write(txd, 6, word); |
1562 | 1562 | ||
1563 | if (skbdesc->desc_len > TXINFO_SIZE) { | 1563 | if (skbdesc->desc_len > TXINFO_SIZE) { |
@@ -2302,9 +2302,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2302 | rt61pci_probe_hw_mode(rt2x00dev); | 2302 | rt61pci_probe_hw_mode(rt2x00dev); |
2303 | 2303 | ||
2304 | /* | 2304 | /* |
2305 | * This device requires firmware. | 2305 | * This device requires firmware and DMA mapped skbs. |
2306 | */ | 2306 | */ |
2307 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2307 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2308 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
2308 | 2309 | ||
2309 | /* | 2310 | /* |
2310 | * Set the rssi offset. | 2311 | * Set the rssi offset. |