Change the number of active antennas (RF-chains)
Okhwan Lee
ohlee at mwnl.snu.ac.kr
Thu Sep 11 00:37:07 PDT 2014
Hi,
I have been trying to configure the number of active antennas (not
spatial stream) by using ath10k/QCA9880.
When I use ath9k, we can easily change the number of active antenna by
using REG_WRITE(ah, AR_PHY_RX_CHAINMASK, ah->rxchainmask) function
used in ar9003_hw_set_chain_masks.
However, in ath10k, we failed to handle the values (e.g, rx/tx chain
mask of QCA9880) by using ath10k_wmi_pdev_set_param(ar,
ar->wmi.pdev_param->rx_chain_mask, rx_ant) funcion in used in
__ath10k_set_antenna.
I use debugfs module to configure the parameters and you can find our
code (for both ath9k and ath10k) at the end of this e-mail.
aWe measured the power consumption of NIC to confirm whether the
codes can change the number of active RF-chains or not.
As you might know, the power consumption is highly depends on the
number of active RF-chains.
In ath9k, the power consumption decreases as the number of active
rf-chains (rx_chainmask, antennas) is decrease.
However, in ath10, we failed to configure the number of active
RF-chains, and the power consumption does not change at all.
If you have any idea on this issue, please let me know.
Thank you.
Okhwan
/********************ath10k/debug.c (this is not work)*********************/
static ssize_t ath10k_read_rx_chainmask(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
// printk(KERN_DEBUG "%s",__FUNCTION__);
ath10k_dbg(ATH10K_DBG_MAC, "%s -> ",__FUNCTION__);
struct ath10k *ar = file->private_data;
char buf[32];
unsigned int len;
len = sprintf(buf, "0x%08x\n", ar->cfg_rx_chainmask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t ath10k_write_rx_chainmask(struct file *file, const char
__user *user_buf,
size_t count, loff_t *ppos)
{
ath10k_dbg(ATH10K_DBG_MAC, "%s -> ",__FUNCTION__);
struct ath10k *ar = file->private_data;
unsigned long mask;
int ret;
ret = kstrtoul_from_user(user_buf, count, 0, &mask);
ath10k_dbg(ATH10K_DBG_MAC, "%s -> mask: 0x%x\n",__FUNCTION__,
(unsigned int)mask);
if (mask > 0x7){
ath10k_dbg(ATH10K_DBG_MAC, "%s -> mask: %lu should be
< 7\n",__FUNCTION__, mask);
return -E2BIG;
}
if ((ar->state != ATH10K_STATE_ON) &&
(ar->state != ATH10K_STATE_RESTARTED)){
ath10k_dbg(ATH10K_DBG_MAC, "%s -> failed pass state
check stat: %d\n",__FUNCTION__, ar->state);
ret = 1;
goto out;
}
ath10k_dbg(ATH10K_DBG_MAC, "%s -> start lock\n",__FUNCTION__);
mutex_lock(&ar->conf_mutex);
ath10k_dbg(ATH10K_DBG_MAC, "%s -> locked\n",__FUNCTION__);
ar->cfg_rx_chainmask = mask;
ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
(u32)mask);
if (ret) {
ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n",
ret, (unsigned int)mask);
goto out;
}
ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
(u32)mask);
ret = count;
out:
mutex_unlock(&ar->conf_mutex);
return ret;
}
static const struct file_operations fops_rx_chainmask = {
.read = ath10k_read_rx_chainmask,
.write = ath10k_write_rx_chainmask,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
/*****************************************/
/********************ath9k/debug.c (this is work)*********************/
static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
printk(KERN_DEBUG “%s”,__FUNCTION__);
struct ath_softc *sc = file->private_data;
struct ath_hw *ah = sc->sc_ah;
char buf[32];
unsigned int len;
len = sprintf(buf, “0x%08x\n”, ah->rxchainmask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_rx_chainmask(struct file *file, const char
__user *user_buf,
size_t count, loff_t *ppos)
{
printk(KERN_DEBUG “%s”,__FUNCTION__);
struct ath_softc *sc = file->private_data;
struct ath_hw *ah = sc->sc_ah;
unsigned long mask;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
buf[len] = ‘\0’;
if (strict_strtoul(buf, 0, &mask))
return -EINVAL;
ah->rxchainmask = mask;
ah->caps.rx_chainmask = mask;
ah->eep_ops->fill_eeprom(ah);
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, ah->rxchainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, ah->rxchainmask);
return count;
}
/*****************************************/
Sincerely yours,
Okhwan Lee , Ph.D. student
Multimedia & Wireless Networking Lab. (MWNL),
School of Electrical Engineering,
Seoul National University (SNU)
Tel: +82-2-880-1755
Cell: +82-10-4632-1980
URL: http://mwnl.snu.ac.kr/~ohlee
More information about the ath10k
mailing list