aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2011-01-31 13:49:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-04 16:29:50 -0500
commit51272292926bc4fff61ba812d5816922b980655b (patch)
treece8f344e2084ff1f82f64052a29c02c58a26cf98 /drivers/net/wireless
parent9be232563666b7d1bd424780aef7ee2aa261ba04 (diff)
zd1211rw: batch beacon config commands together
Beacon config function writes beacon to hw one write per byte. This is very slow (usually taking more than 100ms to finish) and causes high CPU usage when in AP-mode (kworker at ~50% on Intel Atom N270). By batching commands together zd_mac_config_beacon() runtime can be lowered to 1/5th and lower CPU usage to saner levels (<10% on Atom). Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 78c8f8ba50f..84ee1b88691 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -602,11 +602,18 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
602static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) 602static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
603{ 603{
604 struct zd_mac *mac = zd_hw_mac(hw); 604 struct zd_mac *mac = zd_hw_mac(hw);
605 int r, ret; 605 int r, ret, num_cmds, req_pos = 0;
606 u32 tmp, j = 0; 606 u32 tmp, j = 0;
607 /* 4 more bytes for tail CRC */ 607 /* 4 more bytes for tail CRC */
608 u32 full_len = beacon->len + 4; 608 u32 full_len = beacon->len + 4;
609 unsigned long end_jiffies, message_jiffies; 609 unsigned long end_jiffies, message_jiffies;
610 struct zd_ioreq32 *ioreqs;
611
612 /* Alloc memory for full beacon write at once. */
613 num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len;
614 ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL);
615 if (!ioreqs)
616 return -ENOMEM;
610 617
611 mutex_lock(&mac->chip.mutex); 618 mutex_lock(&mac->chip.mutex);
612 619
@@ -637,29 +644,31 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
637 msleep(20); 644 msleep(20);
638 } 645 }
639 646
640 r = zd_iowrite32_locked(&mac->chip, full_len - 1, CR_BCN_FIFO); 647 ioreqs[req_pos].addr = CR_BCN_FIFO;
641 if (r < 0) 648 ioreqs[req_pos].value = full_len - 1;
642 goto release_sema; 649 req_pos++;
643 if (zd_chip_is_zd1211b(&mac->chip)) { 650 if (zd_chip_is_zd1211b(&mac->chip)) {
644 r = zd_iowrite32_locked(&mac->chip, full_len - 1, 651 ioreqs[req_pos].addr = CR_BCN_LENGTH;
645 CR_BCN_LENGTH); 652 ioreqs[req_pos].value = full_len - 1;
646 if (r < 0) 653 req_pos++;
647 goto release_sema;
648 } 654 }
649 655
650 for (j = 0 ; j < beacon->len; j++) { 656 for (j = 0 ; j < beacon->len; j++) {
651 r = zd_iowrite32_locked(&mac->chip, *((u8 *)(beacon->data + j)), 657 ioreqs[req_pos].addr = CR_BCN_FIFO;
652 CR_BCN_FIFO); 658 ioreqs[req_pos].value = *((u8 *)(beacon->data + j));
653 if (r < 0) 659 req_pos++;
654 goto release_sema;
655 } 660 }
656 661
657 for (j = 0; j < 4; j++) { 662 for (j = 0; j < 4; j++) {
658 r = zd_iowrite32_locked(&mac->chip, 0x0, CR_BCN_FIFO); 663 ioreqs[req_pos].addr = CR_BCN_FIFO;
659 if (r < 0) 664 ioreqs[req_pos].value = 0x0;
660 goto release_sema; 665 req_pos++;
661 } 666 }
662 667
668 BUG_ON(req_pos != num_cmds);
669
670 r = zd_iowrite32a_locked(&mac->chip, ioreqs, num_cmds);
671
663release_sema: 672release_sema:
664 /* 673 /*
665 * Try very hard to release device beacon semaphore, as otherwise 674 * Try very hard to release device beacon semaphore, as otherwise
@@ -694,6 +703,7 @@ release_sema:
694 CR_BCN_PLCP_CFG); 703 CR_BCN_PLCP_CFG);
695out: 704out:
696 mutex_unlock(&mac->chip.mutex); 705 mutex_unlock(&mac->chip.mutex);
706 kfree(ioreqs);
697 return r; 707 return r;
698} 708}
699 709