diff options
Diffstat (limited to 'drivers/net/wireless/libertas/wext.c')
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 148 |
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 | */ | ||
131 | static 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 | ||
446 | out: | 420 | out: |
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 | ||
1856 | out: | ||
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 | ||