diff options
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 40 |
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, | |||
602 | static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | 602 | static 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 | |||
663 | release_sema: | 672 | release_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); |
695 | out: | 704 | out: |
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 | ||