aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorGertjan van Wingerde <gwingerde@kpnplanet.nl>2008-06-16 13:56:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 16:49:16 -0400
commitc4da004857056e6ee034c4110ccdcba659077b7e (patch)
tree641f8d9ddab7b8b6ba41fefc57a517abce15e8e6 /drivers/net/wireless/rt2x00/rt2x00dev.c
parent30caa6e3d586442f7c3ad081260ee1b22bb123de (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.c64
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)
468static void rt2x00lib_beacondone_iter(void *data, u8 *mac, 468static 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}
556EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 557EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
557 558
558void rt2x00lib_rxdone(struct queue_entry *entry, 559void 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}
635EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); 661EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
636 662