aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Neal <anna@cozybit.com>2008-09-11 14:17:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-11 15:53:40 -0400
commit0112c9e9e8d47f1d1e6ce1323675cb43ca6aae86 (patch)
tree73a2d11fe479e735b30348eed9e0ac32f130e947
parentaee14ceb5230afb5c17a4e28222ab9734ffd5002 (diff)
libertas: Improvements on automatic tx power control via SIOCSIWTXPOW.
iwconfig txpower can now be used to set tx power to fixed or auto. If set to auto the default firmware settings are used. The command CMD_802_11_PA_CFG is only sent to older firmware, as Dan Williams noted the command was no longer supported in firmware V9+. Signed-off-by: Anna Neal <anna@cozybit.com> Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/libertas/cmd.c64
-rw-r--r--drivers/net/wireless/libertas/cmd.h6
-rw-r--r--drivers/net/wireless/libertas/defs.h9
-rw-r--r--drivers/net/wireless/libertas/host.h1
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h24
-rw-r--r--drivers/net/wireless/libertas/wext.c31
6 files changed, 128 insertions, 7 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 802547e79671..5fef05f3cd00 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1971,6 +1971,70 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
1971} 1971}
1972 1972
1973 1973
1974/**
1975 * @brief Configures the transmission power control functionality.
1976 *
1977 * @param priv A pointer to struct lbs_private structure
1978 * @param enable Transmission power control enable
1979 * @param p0 Power level when link quality is good (dBm).
1980 * @param p1 Power level when link quality is fair (dBm).
1981 * @param p2 Power level when link quality is poor (dBm).
1982 * @param usesnr Use Signal to Noise Ratio in TPC
1983 *
1984 * @return 0 on success
1985 */
1986int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
1987 int8_t p2, int usesnr)
1988{
1989 struct cmd_ds_802_11_tpc_cfg cmd;
1990 int ret;
1991
1992 memset(&cmd, 0, sizeof(cmd));
1993 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1994 cmd.action = cpu_to_le16(CMD_ACT_SET);
1995 cmd.enable = !!enable;
1996 cmd.usesnr = !!enable;
1997 cmd.P0 = p0;
1998 cmd.P1 = p1;
1999 cmd.P2 = p2;
2000
2001 ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
2002
2003 return ret;
2004}
2005
2006/**
2007 * @brief Configures the power adaptation settings.
2008 *
2009 * @param priv A pointer to struct lbs_private structure
2010 * @param enable Power adaptation enable
2011 * @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm).
2012 * @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
2013 * @param p2 Power level for 48 and 54 Mbps (dBm).
2014 *
2015 * @return 0 on Success
2016 */
2017
2018int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
2019 int8_t p1, int8_t p2)
2020{
2021 struct cmd_ds_802_11_pa_cfg cmd;
2022 int ret;
2023
2024 memset(&cmd, 0, sizeof(cmd));
2025 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2026 cmd.action = cpu_to_le16(CMD_ACT_SET);
2027 cmd.enable = !!enable;
2028 cmd.P0 = p0;
2029 cmd.P1 = p1;
2030 cmd.P2 = p2;
2031
2032 ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
2033
2034 return ret;
2035}
2036
2037
1974static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, 2038static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1975 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, 2039 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
1976 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 2040 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 11ac996e895e..336a181d857a 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -26,6 +26,12 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
26 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 26 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
27 unsigned long callback_arg); 27 unsigned long callback_arg);
28 28
29int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
30 int8_t p1, int8_t p2);
31
32int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
33 int8_t p2, int usesnr);
34
29int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, 35int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
30 struct cmd_header *resp); 36 struct cmd_header *resp);
31 37
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 4b2428ac2223..c89d7a1041a8 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -189,6 +189,15 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
189#define MRVDRV_CMD_UPLD_RDY 0x0008 189#define MRVDRV_CMD_UPLD_RDY 0x0008
190#define MRVDRV_CARDEVENT 0x0010 190#define MRVDRV_CARDEVENT 0x0010
191 191
192
193/* Automatic TX control default levels */
194#define POW_ADAPT_DEFAULT_P0 13
195#define POW_ADAPT_DEFAULT_P1 15
196#define POW_ADAPT_DEFAULT_P2 18
197#define TPC_DEFAULT_P0 5
198#define TPC_DEFAULT_P1 10
199#define TPC_DEFAULT_P2 13
200
192/** TxPD status */ 201/** TxPD status */
193 202
194/* Station firmware use TxPD status field to report final Tx transmit 203/* Station firmware use TxPD status field to report final Tx transmit
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index da618fc997ce..a916bb9bd5da 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -83,6 +83,7 @@
83#define CMD_802_11_INACTIVITY_TIMEOUT 0x0067 83#define CMD_802_11_INACTIVITY_TIMEOUT 0x0067
84#define CMD_802_11_SLEEP_PERIOD 0x0068 84#define CMD_802_11_SLEEP_PERIOD 0x0068
85#define CMD_802_11_TPC_CFG 0x0072 85#define CMD_802_11_TPC_CFG 0x0072
86#define CMD_802_11_PA_CFG 0x0073
86#define CMD_802_11_FW_WAKE_METHOD 0x0074 87#define CMD_802_11_FW_WAKE_METHOD 0x0074
87#define CMD_802_11_SUBSCRIBE_EVENT 0x0075 88#define CMD_802_11_SUBSCRIBE_EVENT 0x0075
88#define CMD_802_11_RATE_ADAPT_RATESET 0x0076 89#define CMD_802_11_RATE_ADAPT_RATESET 0x0076
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index d27c276b2191..630b79967560 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -607,14 +607,28 @@ struct cmd_ds_802_11_eeprom_access {
607} __attribute__ ((packed)); 607} __attribute__ ((packed));
608 608
609struct cmd_ds_802_11_tpc_cfg { 609struct cmd_ds_802_11_tpc_cfg {
610 struct cmd_header hdr;
611
610 __le16 action; 612 __le16 action;
611 u8 enable; 613 uint8_t enable;
612 s8 P0; 614 int8_t P0;
613 s8 P1; 615 int8_t P1;
614 s8 P2; 616 int8_t P2;
615 u8 usesnr; 617 uint8_t usesnr;
616} __attribute__ ((packed)); 618} __attribute__ ((packed));
617 619
620
621struct cmd_ds_802_11_pa_cfg {
622 struct cmd_header hdr;
623
624 __le16 action;
625 uint8_t enable;
626 int8_t P0;
627 int8_t P1;
628 int8_t P2;
629} __attribute__ ((packed));
630
631
618struct cmd_ds_802_11_led_ctrl { 632struct cmd_ds_802_11_led_ctrl {
619 __le16 action; 633 __le16 action;
620 __le16 numled; 634 __le16 numled;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 426f1fe3bb42..e8cadad2c863 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1820,7 +1820,21 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1820 } 1820 }
1821 1821
1822 if (vwrq->fixed == 0) { 1822 if (vwrq->fixed == 0) {
1823 /* Auto power control */ 1823 /* User requests automatic tx power control, however there are
1824 * many auto tx settings. For now use firmware defaults until
1825 * we come up with a good way to expose these to the user. */
1826 if (priv->fwrelease < 0x09000000) {
1827 ret = lbs_set_power_adapt_cfg(priv, 1,
1828 POW_ADAPT_DEFAULT_P0,
1829 POW_ADAPT_DEFAULT_P1,
1830 POW_ADAPT_DEFAULT_P2);
1831 if (ret)
1832 goto out;
1833 }
1834 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
1835 TPC_DEFAULT_P2, 1);
1836 if (ret)
1837 goto out;
1824 dbm = priv->txpower_max; 1838 dbm = priv->txpower_max;
1825 } else { 1839 } else {
1826 /* Userspace check in iwrange if it should use dBm or mW, 1840 /* Userspace check in iwrange if it should use dBm or mW,
@@ -1830,7 +1844,8 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1830 goto out; 1844 goto out;
1831 } 1845 }
1832 1846
1833 /* Validate requested power level against firmware allowed levels */ 1847 /* Validate requested power level against firmware allowed
1848 * levels */
1834 if (priv->txpower_min && (dbm < priv->txpower_min)) { 1849 if (priv->txpower_min && (dbm < priv->txpower_min)) {
1835 ret = -EINVAL; 1850 ret = -EINVAL;
1836 goto out; 1851 goto out;
@@ -1840,6 +1855,18 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1840 ret = -EINVAL; 1855 ret = -EINVAL;
1841 goto out; 1856 goto out;
1842 } 1857 }
1858 if (priv->fwrelease < 0x09000000) {
1859 ret = lbs_set_power_adapt_cfg(priv, 0,
1860 POW_ADAPT_DEFAULT_P0,
1861 POW_ADAPT_DEFAULT_P1,
1862 POW_ADAPT_DEFAULT_P2);
1863 if (ret)
1864 goto out;
1865 }
1866 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
1867 TPC_DEFAULT_P2, 1);
1868 if (ret)
1869 goto out;
1843 } 1870 }
1844 1871
1845 /* If the radio was off, turn it on */ 1872 /* If the radio was off, turn it on */