From: Jussi Kivilinna Date: Mon, 31 Jan 2011 18:49:05 +0000 (+0200) Subject: zd1211rw: batch beacon config commands together X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=51272292926bc4fff61ba812d5816922b980655b;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git 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 Signed-off-by: John W. Linville --- diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 78c8f8ba50f6..84ee1b886912 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, static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) { struct zd_mac *mac = zd_hw_mac(hw); - int r, ret; + int r, ret, num_cmds, req_pos = 0; u32 tmp, j = 0; /* 4 more bytes for tail CRC */ u32 full_len = beacon->len + 4; unsigned long end_jiffies, message_jiffies; + struct zd_ioreq32 *ioreqs; + + /* Alloc memory for full beacon write at once. */ + num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; + ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); + if (!ioreqs) + return -ENOMEM; mutex_lock(&mac->chip.mutex); @@ -637,29 +644,31 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) msleep(20); } - r = zd_iowrite32_locked(&mac->chip, full_len - 1, CR_BCN_FIFO); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_FIFO; + ioreqs[req_pos].value = full_len - 1; + req_pos++; if (zd_chip_is_zd1211b(&mac->chip)) { - r = zd_iowrite32_locked(&mac->chip, full_len - 1, - CR_BCN_LENGTH); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_LENGTH; + ioreqs[req_pos].value = full_len - 1; + req_pos++; } for (j = 0 ; j < beacon->len; j++) { - r = zd_iowrite32_locked(&mac->chip, *((u8 *)(beacon->data + j)), - CR_BCN_FIFO); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_FIFO; + ioreqs[req_pos].value = *((u8 *)(beacon->data + j)); + req_pos++; } for (j = 0; j < 4; j++) { - r = zd_iowrite32_locked(&mac->chip, 0x0, CR_BCN_FIFO); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_FIFO; + ioreqs[req_pos].value = 0x0; + req_pos++; } + BUG_ON(req_pos != num_cmds); + + r = zd_iowrite32a_locked(&mac->chip, ioreqs, num_cmds); + release_sema: /* * Try very hard to release device beacon semaphore, as otherwise @@ -694,6 +703,7 @@ release_sema: CR_BCN_PLCP_CFG); out: mutex_unlock(&mac->chip.mutex); + kfree(ioreqs); return r; }