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/wireless/rt2x00/rt2x00dev.c | |
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/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 64 |
1 files changed, 45 insertions, 19 deletions
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 | ||