aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/wext.c')
-rw-r--r--drivers/net/wireless/libertas/wext.c148
1 files changed, 69 insertions, 79 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 8b3ed77860b3..426f1fe3bb42 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -120,34 +120,6 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(
120 return cfp; 120 return cfp;
121} 121}
122 122
123
124/**
125 * @brief Set Radio On/OFF
126 *
127 * @param priv A pointer to struct lbs_private structure
128 * @option Radio Option
129 * @return 0 --success, otherwise fail
130 */
131static int lbs_radio_ioctl(struct lbs_private *priv, u8 option)
132{
133 int ret = 0;
134
135 lbs_deb_enter(LBS_DEB_WEXT);
136
137 if (priv->radioon != option) {
138 lbs_deb_wext("switching radio %s\n", option ? "on" : "off");
139 priv->radioon = option;
140
141 ret = lbs_prepare_and_send_command(priv,
142 CMD_802_11_RADIO_CONTROL,
143 CMD_ACT_SET,
144 CMD_OPTION_WAITFORRSP, 0, NULL);
145 }
146
147 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
148 return ret;
149}
150
151/** 123/**
152 * @brief Copy active data rates based on adapter mode and status 124 * @brief Copy active data rates based on adapter mode and status
153 * 125 *
@@ -420,28 +392,30 @@ static int lbs_get_txpow(struct net_device *dev,
420 struct iw_request_info *info, 392 struct iw_request_info *info,
421 struct iw_param *vwrq, char *extra) 393 struct iw_param *vwrq, char *extra)
422{ 394{
423 int ret = 0;
424 struct lbs_private *priv = dev->priv; 395 struct lbs_private *priv = dev->priv;
396 s16 curlevel = 0;
397 int ret = 0;
425 398
426 lbs_deb_enter(LBS_DEB_WEXT); 399 lbs_deb_enter(LBS_DEB_WEXT);
427 400
428 ret = lbs_prepare_and_send_command(priv, 401 if (!priv->radio_on) {
429 CMD_802_11_RF_TX_POWER, 402 lbs_deb_wext("tx power off\n");
430 CMD_ACT_TX_POWER_OPT_GET, 403 vwrq->value = 0;
431 CMD_OPTION_WAITFORRSP, 0, NULL); 404 vwrq->disabled = 1;
405 goto out;
406 }
432 407
408 ret = lbs_get_tx_power(priv, &curlevel, NULL, NULL);
433 if (ret) 409 if (ret)
434 goto out; 410 goto out;
435 411
436 lbs_deb_wext("tx power level %d dbm\n", priv->txpowerlevel); 412 lbs_deb_wext("tx power level %d dbm\n", curlevel);
437 vwrq->value = priv->txpowerlevel; 413 priv->txpower_cur = curlevel;
414
415 vwrq->value = curlevel;
438 vwrq->fixed = 1; 416 vwrq->fixed = 1;
439 if (priv->radioon) { 417 vwrq->disabled = 0;
440 vwrq->disabled = 0; 418 vwrq->flags = IW_TXPOW_DBM;
441 vwrq->flags = IW_TXPOW_DBM;
442 } else {
443 vwrq->disabled = 1;
444 }
445 419
446out: 420out:
447 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 421 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
@@ -693,22 +667,12 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
693 667
694 range->sensitivity = 0; 668 range->sensitivity = 0;
695 669
696 /* 670 /* Setup the supported power level ranges */
697 * Setup the supported power level ranges
698 */
699 memset(range->txpower, 0, sizeof(range->txpower)); 671 memset(range->txpower, 0, sizeof(range->txpower));
700 range->txpower[0] = 5; 672 range->txpower_capa = IW_TXPOW_DBM | IW_TXPOW_RANGE;
701 range->txpower[1] = 7; 673 range->txpower[0] = priv->txpower_min;
702 range->txpower[2] = 9; 674 range->txpower[1] = priv->txpower_max;
703 range->txpower[3] = 11; 675 range->num_txpower = 2;
704 range->txpower[4] = 13;
705 range->txpower[5] = 15;
706 range->txpower[6] = 17;
707 range->txpower[7] = 19;
708
709 range->num_txpower = 8;
710 range->txpower_capa = IW_TXPOW_DBM;
711 range->txpower_capa |= IW_TXPOW_RANGE;
712 676
713 range->event_capa[0] = (IW_EVENT_CAPA_K_0 | 677 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
714 IW_EVENT_CAPA_MASK(SIOCGIWAP) | 678 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
@@ -998,9 +962,11 @@ static int lbs_mesh_set_freq(struct net_device *dev,
998 if (fwrq->m != priv->curbssparams.channel) { 962 if (fwrq->m != priv->curbssparams.channel) {
999 lbs_deb_wext("mesh channel change forces eth disconnect\n"); 963 lbs_deb_wext("mesh channel change forces eth disconnect\n");
1000 if (priv->mode == IW_MODE_INFRA) 964 if (priv->mode == IW_MODE_INFRA)
1001 lbs_send_deauthentication(priv); 965 lbs_cmd_80211_deauthenticate(priv,
966 priv->curbssparams.bssid,
967 WLAN_REASON_DEAUTH_LEAVING);
1002 else if (priv->mode == IW_MODE_ADHOC) 968 else if (priv->mode == IW_MODE_ADHOC)
1003 lbs_stop_adhoc_network(priv); 969 lbs_adhoc_stop(priv);
1004 } 970 }
1005 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m); 971 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
1006 lbs_update_channel(priv); 972 lbs_update_channel(priv);
@@ -1844,39 +1810,50 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1844{ 1810{
1845 int ret = 0; 1811 int ret = 0;
1846 struct lbs_private *priv = dev->priv; 1812 struct lbs_private *priv = dev->priv;
1847 1813 s16 dbm = (s16) vwrq->value;
1848 u16 dbm;
1849 1814
1850 lbs_deb_enter(LBS_DEB_WEXT); 1815 lbs_deb_enter(LBS_DEB_WEXT);
1851 1816
1852 if (vwrq->disabled) { 1817 if (vwrq->disabled) {
1853 lbs_radio_ioctl(priv, RADIO_OFF); 1818 lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0);
1854 return 0; 1819 goto out;
1855 } 1820 }
1856 1821
1857 priv->preamble = CMD_TYPE_AUTO_PREAMBLE; 1822 if (vwrq->fixed == 0) {
1858 1823 /* Auto power control */
1859 lbs_radio_ioctl(priv, RADIO_ON); 1824 dbm = priv->txpower_max;
1825 } else {
1826 /* Userspace check in iwrange if it should use dBm or mW,
1827 * therefore this should never happen... Jean II */
1828 if ((vwrq->flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
1829 ret = -EOPNOTSUPP;
1830 goto out;
1831 }
1860 1832
1861 /* Userspace check in iwrange if it should use dBm or mW, 1833 /* Validate requested power level against firmware allowed levels */
1862 * therefore this should never happen... Jean II */ 1834 if (priv->txpower_min && (dbm < priv->txpower_min)) {
1863 if ((vwrq->flags & IW_TXPOW_TYPE) == IW_TXPOW_MWATT) { 1835 ret = -EINVAL;
1864 return -EOPNOTSUPP; 1836 goto out;
1865 } else 1837 }
1866 dbm = (u16) vwrq->value;
1867 1838
1868 /* auto tx power control */ 1839 if (priv->txpower_max && (dbm > priv->txpower_max)) {
1840 ret = -EINVAL;
1841 goto out;
1842 }
1843 }
1869 1844
1870 if (vwrq->fixed == 0) 1845 /* If the radio was off, turn it on */
1871 dbm = 0xffff; 1846 if (!priv->radio_on) {
1847 ret = lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 1);
1848 if (ret)
1849 goto out;
1850 }
1872 1851
1873 lbs_deb_wext("txpower set %d dbm\n", dbm); 1852 lbs_deb_wext("txpower set %d dBm\n", dbm);
1874 1853
1875 ret = lbs_prepare_and_send_command(priv, 1854 ret = lbs_set_tx_power(priv, dbm);
1876 CMD_802_11_RF_TX_POWER,
1877 CMD_ACT_TX_POWER_OPT_SET_LOW,
1878 CMD_OPTION_WAITFORRSP, 0, (void *)&dbm);
1879 1855
1856out:
1880 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1857 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1881 return ret; 1858 return ret;
1882} 1859}
@@ -1928,6 +1905,11 @@ static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
1928 1905
1929 lbs_deb_enter(LBS_DEB_WEXT); 1906 lbs_deb_enter(LBS_DEB_WEXT);
1930 1907
1908 if (!priv->radio_on) {
1909 ret = -EINVAL;
1910 goto out;
1911 }
1912
1931 /* Check the size of the string */ 1913 /* Check the size of the string */
1932 if (in_ssid_len > IW_ESSID_MAX_SIZE) { 1914 if (in_ssid_len > IW_ESSID_MAX_SIZE) {
1933 ret = -E2BIG; 1915 ret = -E2BIG;
@@ -2005,6 +1987,11 @@ static int lbs_mesh_set_essid(struct net_device *dev,
2005 1987
2006 lbs_deb_enter(LBS_DEB_WEXT); 1988 lbs_deb_enter(LBS_DEB_WEXT);
2007 1989
1990 if (!priv->radio_on) {
1991 ret = -EINVAL;
1992 goto out;
1993 }
1994
2008 /* Check the size of the string */ 1995 /* Check the size of the string */
2009 if (dwrq->length > IW_ESSID_MAX_SIZE) { 1996 if (dwrq->length > IW_ESSID_MAX_SIZE) {
2010 ret = -E2BIG; 1997 ret = -E2BIG;
@@ -2046,6 +2033,9 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
2046 2033
2047 lbs_deb_enter(LBS_DEB_WEXT); 2034 lbs_deb_enter(LBS_DEB_WEXT);
2048 2035
2036 if (!priv->radio_on)
2037 return -EINVAL;
2038
2049 if (awrq->sa_family != ARPHRD_ETHER) 2039 if (awrq->sa_family != ARPHRD_ETHER)
2050 return -EINVAL; 2040 return -EINVAL;
2051 2041