aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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