diff options
Diffstat (limited to 'drivers/net/wireless/libertas/wext.c')
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 185 |
1 files changed, 183 insertions, 2 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index be837a0d2517..38a451edb703 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
@@ -45,6 +45,31 @@ static inline void lbs_cancel_association_work(struct lbs_private *priv) | |||
45 | priv->pending_assoc_req = NULL; | 45 | priv->pending_assoc_req = NULL; |
46 | } | 46 | } |
47 | 47 | ||
48 | /** | ||
49 | * @brief This function checks if the command is allowed. | ||
50 | * | ||
51 | * @param priv A pointer to lbs_private structure | ||
52 | * @return allowed or not allowed. | ||
53 | */ | ||
54 | |||
55 | int lbs_is_cmd_allowed(struct lbs_private *priv) | ||
56 | { | ||
57 | int ret = 1; | ||
58 | |||
59 | lbs_deb_enter(LBS_DEB_WEXT); | ||
60 | |||
61 | if (!priv->is_auto_deep_sleep_enabled) { | ||
62 | if (priv->is_deep_sleep) { | ||
63 | lbs_deb_wext("IOCTLS called when station" | ||
64 | "is in deep sleep\n"); | ||
65 | ret = 0; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | lbs_deb_leave(LBS_DEB_WEXT); | ||
70 | return ret; | ||
71 | } | ||
72 | |||
48 | 73 | ||
49 | /** | 74 | /** |
50 | * @brief Find the channel frequency power info with specific channel | 75 | * @brief Find the channel frequency power info with specific channel |
@@ -168,6 +193,11 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, | |||
168 | 193 | ||
169 | lbs_deb_enter(LBS_DEB_WEXT); | 194 | lbs_deb_enter(LBS_DEB_WEXT); |
170 | 195 | ||
196 | if (!lbs_is_cmd_allowed(priv)) { | ||
197 | lbs_deb_leave(LBS_DEB_WEXT); | ||
198 | return -EBUSY; | ||
199 | } | ||
200 | |||
171 | cfp = lbs_find_cfp_by_band_and_channel(priv, 0, | 201 | cfp = lbs_find_cfp_by_band_and_channel(priv, 0, |
172 | priv->curbssparams.channel); | 202 | priv->curbssparams.channel); |
173 | 203 | ||
@@ -278,6 +308,12 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, | |||
278 | 308 | ||
279 | lbs_deb_enter(LBS_DEB_WEXT); | 309 | lbs_deb_enter(LBS_DEB_WEXT); |
280 | 310 | ||
311 | if (!lbs_is_cmd_allowed(priv)) { | ||
312 | ret = -EBUSY; | ||
313 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
314 | return ret; | ||
315 | } | ||
316 | |||
281 | if (vwrq->disabled) | 317 | if (vwrq->disabled) |
282 | val = MRVDRV_RTS_MAX_VALUE; | 318 | val = MRVDRV_RTS_MAX_VALUE; |
283 | 319 | ||
@@ -299,6 +335,11 @@ static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info, | |||
299 | 335 | ||
300 | lbs_deb_enter(LBS_DEB_WEXT); | 336 | lbs_deb_enter(LBS_DEB_WEXT); |
301 | 337 | ||
338 | if (!lbs_is_cmd_allowed(priv)) { | ||
339 | ret = -EBUSY; | ||
340 | goto out; | ||
341 | } | ||
342 | |||
302 | ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val); | 343 | ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val); |
303 | if (ret) | 344 | if (ret) |
304 | goto out; | 345 | goto out; |
@@ -321,6 +362,12 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, | |||
321 | 362 | ||
322 | lbs_deb_enter(LBS_DEB_WEXT); | 363 | lbs_deb_enter(LBS_DEB_WEXT); |
323 | 364 | ||
365 | if (!lbs_is_cmd_allowed(priv)) { | ||
366 | ret = -EBUSY; | ||
367 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
368 | return ret; | ||
369 | } | ||
370 | |||
324 | if (vwrq->disabled) | 371 | if (vwrq->disabled) |
325 | val = MRVDRV_FRAG_MAX_VALUE; | 372 | val = MRVDRV_FRAG_MAX_VALUE; |
326 | 373 | ||
@@ -342,6 +389,11 @@ static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info, | |||
342 | 389 | ||
343 | lbs_deb_enter(LBS_DEB_WEXT); | 390 | lbs_deb_enter(LBS_DEB_WEXT); |
344 | 391 | ||
392 | if (!lbs_is_cmd_allowed(priv)) { | ||
393 | ret = -EBUSY; | ||
394 | goto out; | ||
395 | } | ||
396 | |||
345 | ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val); | 397 | ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val); |
346 | if (ret) | 398 | if (ret) |
347 | goto out; | 399 | goto out; |
@@ -391,6 +443,11 @@ static int lbs_get_txpow(struct net_device *dev, | |||
391 | 443 | ||
392 | lbs_deb_enter(LBS_DEB_WEXT); | 444 | lbs_deb_enter(LBS_DEB_WEXT); |
393 | 445 | ||
446 | if (!lbs_is_cmd_allowed(priv)) { | ||
447 | ret = -EBUSY; | ||
448 | goto out; | ||
449 | } | ||
450 | |||
394 | if (!priv->radio_on) { | 451 | if (!priv->radio_on) { |
395 | lbs_deb_wext("tx power off\n"); | 452 | lbs_deb_wext("tx power off\n"); |
396 | vwrq->value = 0; | 453 | vwrq->value = 0; |
@@ -424,6 +481,11 @@ static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info, | |||
424 | 481 | ||
425 | lbs_deb_enter(LBS_DEB_WEXT); | 482 | lbs_deb_enter(LBS_DEB_WEXT); |
426 | 483 | ||
484 | if (!lbs_is_cmd_allowed(priv)) { | ||
485 | ret = -EBUSY; | ||
486 | goto out; | ||
487 | } | ||
488 | |||
427 | if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) | 489 | if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) |
428 | return -EOPNOTSUPP; | 490 | return -EOPNOTSUPP; |
429 | 491 | ||
@@ -472,6 +534,11 @@ static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info, | |||
472 | 534 | ||
473 | lbs_deb_enter(LBS_DEB_WEXT); | 535 | lbs_deb_enter(LBS_DEB_WEXT); |
474 | 536 | ||
537 | if (!lbs_is_cmd_allowed(priv)) { | ||
538 | ret = -EBUSY; | ||
539 | goto out; | ||
540 | } | ||
541 | |||
475 | vwrq->disabled = 0; | 542 | vwrq->disabled = 0; |
476 | 543 | ||
477 | if (vwrq->flags & IW_RETRY_LONG) { | 544 | if (vwrq->flags & IW_RETRY_LONG) { |
@@ -709,6 +776,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, | |||
709 | struct iw_param *vwrq, char *extra) | 776 | struct iw_param *vwrq, char *extra) |
710 | { | 777 | { |
711 | struct lbs_private *priv = dev->ml_priv; | 778 | struct lbs_private *priv = dev->ml_priv; |
779 | int ret = 0; | ||
712 | 780 | ||
713 | lbs_deb_enter(LBS_DEB_WEXT); | 781 | lbs_deb_enter(LBS_DEB_WEXT); |
714 | 782 | ||
@@ -737,8 +805,54 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, | |||
737 | "setting power timeout is not supported\n"); | 805 | "setting power timeout is not supported\n"); |
738 | return -EINVAL; | 806 | return -EINVAL; |
739 | } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { | 807 | } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { |
740 | lbs_deb_wext("setting power period not supported\n"); | 808 | vwrq->value = vwrq->value / 1000; |
741 | return -EINVAL; | 809 | if (!priv->enter_deep_sleep) { |
810 | lbs_pr_err("deep sleep feature is not implemented " | ||
811 | "for this interface driver\n"); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | |||
815 | if (priv->connect_status == LBS_CONNECTED) { | ||
816 | if ((priv->is_auto_deep_sleep_enabled) && | ||
817 | (vwrq->value == -1000)) { | ||
818 | lbs_exit_auto_deep_sleep(priv); | ||
819 | return 0; | ||
820 | } else { | ||
821 | lbs_pr_err("can't use deep sleep cmd in " | ||
822 | "connected state\n"); | ||
823 | return -EINVAL; | ||
824 | } | ||
825 | } | ||
826 | |||
827 | if ((vwrq->value < 0) && (vwrq->value != -1000)) { | ||
828 | lbs_pr_err("unknown option\n"); | ||
829 | return -EINVAL; | ||
830 | } | ||
831 | |||
832 | if (vwrq->value > 0) { | ||
833 | if (!priv->is_auto_deep_sleep_enabled) { | ||
834 | priv->is_activity_detected = 0; | ||
835 | priv->auto_deep_sleep_timeout = vwrq->value; | ||
836 | lbs_enter_auto_deep_sleep(priv); | ||
837 | } else { | ||
838 | priv->auto_deep_sleep_timeout = vwrq->value; | ||
839 | lbs_deb_debugfs("auto deep sleep: " | ||
840 | "already enabled\n"); | ||
841 | } | ||
842 | return 0; | ||
843 | } else { | ||
844 | if (priv->is_auto_deep_sleep_enabled) { | ||
845 | lbs_exit_auto_deep_sleep(priv); | ||
846 | /* Try to exit deep sleep if auto */ | ||
847 | /*deep sleep disabled */ | ||
848 | ret = lbs_set_deep_sleep(priv, 0); | ||
849 | } | ||
850 | if (vwrq->value == 0) | ||
851 | ret = lbs_set_deep_sleep(priv, 1); | ||
852 | else if (vwrq->value == -1000) | ||
853 | ret = lbs_set_deep_sleep(priv, 0); | ||
854 | return ret; | ||
855 | } | ||
742 | } | 856 | } |
743 | 857 | ||
744 | if (priv->psmode != LBS802_11POWERMODECAM) { | 858 | if (priv->psmode != LBS802_11POWERMODECAM) { |
@@ -752,6 +866,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, | |||
752 | } | 866 | } |
753 | 867 | ||
754 | lbs_deb_leave(LBS_DEB_WEXT); | 868 | lbs_deb_leave(LBS_DEB_WEXT); |
869 | |||
755 | return 0; | 870 | return 0; |
756 | } | 871 | } |
757 | 872 | ||
@@ -792,6 +907,9 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) | |||
792 | 907 | ||
793 | lbs_deb_enter(LBS_DEB_WEXT); | 908 | lbs_deb_enter(LBS_DEB_WEXT); |
794 | 909 | ||
910 | if (!lbs_is_cmd_allowed(priv)) | ||
911 | return NULL; | ||
912 | |||
795 | priv->wstats.status = priv->mode; | 913 | priv->wstats.status = priv->mode; |
796 | 914 | ||
797 | /* If we're not associated, all quality values are meaningless */ | 915 | /* If we're not associated, all quality values are meaningless */ |
@@ -892,6 +1010,12 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info, | |||
892 | 1010 | ||
893 | lbs_deb_enter(LBS_DEB_WEXT); | 1011 | lbs_deb_enter(LBS_DEB_WEXT); |
894 | 1012 | ||
1013 | if (!lbs_is_cmd_allowed(priv)) { | ||
1014 | ret = -EBUSY; | ||
1015 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
1016 | return ret; | ||
1017 | } | ||
1018 | |||
895 | mutex_lock(&priv->lock); | 1019 | mutex_lock(&priv->lock); |
896 | assoc_req = lbs_get_association_request(priv); | 1020 | assoc_req = lbs_get_association_request(priv); |
897 | if (!assoc_req) { | 1021 | if (!assoc_req) { |
@@ -1000,6 +1124,12 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, | |||
1000 | u8 rates[MAX_RATES + 1]; | 1124 | u8 rates[MAX_RATES + 1]; |
1001 | 1125 | ||
1002 | lbs_deb_enter(LBS_DEB_WEXT); | 1126 | lbs_deb_enter(LBS_DEB_WEXT); |
1127 | |||
1128 | if (!lbs_is_cmd_allowed(priv)) { | ||
1129 | ret = -EBUSY; | ||
1130 | goto out; | ||
1131 | } | ||
1132 | |||
1003 | lbs_deb_wext("vwrq->value %d\n", vwrq->value); | 1133 | lbs_deb_wext("vwrq->value %d\n", vwrq->value); |
1004 | lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed); | 1134 | lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed); |
1005 | 1135 | ||
@@ -1058,6 +1188,11 @@ static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, | |||
1058 | 1188 | ||
1059 | lbs_deb_enter(LBS_DEB_WEXT); | 1189 | lbs_deb_enter(LBS_DEB_WEXT); |
1060 | 1190 | ||
1191 | if (!lbs_is_cmd_allowed(priv)) { | ||
1192 | lbs_deb_leave(LBS_DEB_WEXT); | ||
1193 | return -EBUSY; | ||
1194 | } | ||
1195 | |||
1061 | if (priv->connect_status == LBS_CONNECTED) { | 1196 | if (priv->connect_status == LBS_CONNECTED) { |
1062 | vwrq->value = priv->cur_rate * 500000; | 1197 | vwrq->value = priv->cur_rate * 500000; |
1063 | 1198 | ||
@@ -1084,6 +1219,11 @@ static int lbs_set_mode(struct net_device *dev, | |||
1084 | 1219 | ||
1085 | lbs_deb_enter(LBS_DEB_WEXT); | 1220 | lbs_deb_enter(LBS_DEB_WEXT); |
1086 | 1221 | ||
1222 | if (!lbs_is_cmd_allowed(priv)) { | ||
1223 | ret = -EBUSY; | ||
1224 | goto out; | ||
1225 | } | ||
1226 | |||
1087 | if ( (*uwrq != IW_MODE_ADHOC) | 1227 | if ( (*uwrq != IW_MODE_ADHOC) |
1088 | && (*uwrq != IW_MODE_INFRA) | 1228 | && (*uwrq != IW_MODE_INFRA) |
1089 | && (*uwrq != IW_MODE_AUTO)) { | 1229 | && (*uwrq != IW_MODE_AUTO)) { |
@@ -1325,6 +1465,12 @@ static int lbs_set_encode(struct net_device *dev, | |||
1325 | 1465 | ||
1326 | lbs_deb_enter(LBS_DEB_WEXT); | 1466 | lbs_deb_enter(LBS_DEB_WEXT); |
1327 | 1467 | ||
1468 | if (!lbs_is_cmd_allowed(priv)) { | ||
1469 | ret = -EBUSY; | ||
1470 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
1471 | return ret; | ||
1472 | } | ||
1473 | |||
1328 | mutex_lock(&priv->lock); | 1474 | mutex_lock(&priv->lock); |
1329 | assoc_req = lbs_get_association_request(priv); | 1475 | assoc_req = lbs_get_association_request(priv); |
1330 | if (!assoc_req) { | 1476 | if (!assoc_req) { |
@@ -1508,6 +1654,12 @@ static int lbs_set_encodeext(struct net_device *dev, | |||
1508 | 1654 | ||
1509 | lbs_deb_enter(LBS_DEB_WEXT); | 1655 | lbs_deb_enter(LBS_DEB_WEXT); |
1510 | 1656 | ||
1657 | if (!lbs_is_cmd_allowed(priv)) { | ||
1658 | ret = -EBUSY; | ||
1659 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
1660 | return ret; | ||
1661 | } | ||
1662 | |||
1511 | mutex_lock(&priv->lock); | 1663 | mutex_lock(&priv->lock); |
1512 | assoc_req = lbs_get_association_request(priv); | 1664 | assoc_req = lbs_get_association_request(priv); |
1513 | if (!assoc_req) { | 1665 | if (!assoc_req) { |
@@ -1720,6 +1872,12 @@ static int lbs_set_auth(struct net_device *dev, | |||
1720 | 1872 | ||
1721 | lbs_deb_enter(LBS_DEB_WEXT); | 1873 | lbs_deb_enter(LBS_DEB_WEXT); |
1722 | 1874 | ||
1875 | if (!lbs_is_cmd_allowed(priv)) { | ||
1876 | ret = -EBUSY; | ||
1877 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
1878 | return ret; | ||
1879 | } | ||
1880 | |||
1723 | mutex_lock(&priv->lock); | 1881 | mutex_lock(&priv->lock); |
1724 | assoc_req = lbs_get_association_request(priv); | 1882 | assoc_req = lbs_get_association_request(priv); |
1725 | if (!assoc_req) { | 1883 | if (!assoc_req) { |
@@ -1822,6 +1980,12 @@ static int lbs_get_auth(struct net_device *dev, | |||
1822 | 1980 | ||
1823 | lbs_deb_enter(LBS_DEB_WEXT); | 1981 | lbs_deb_enter(LBS_DEB_WEXT); |
1824 | 1982 | ||
1983 | if (!lbs_is_cmd_allowed(priv)) { | ||
1984 | ret = -EBUSY; | ||
1985 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
1986 | return ret; | ||
1987 | } | ||
1988 | |||
1825 | switch (dwrq->flags & IW_AUTH_INDEX) { | 1989 | switch (dwrq->flags & IW_AUTH_INDEX) { |
1826 | case IW_AUTH_KEY_MGMT: | 1990 | case IW_AUTH_KEY_MGMT: |
1827 | dwrq->value = priv->secinfo.key_mgmt; | 1991 | dwrq->value = priv->secinfo.key_mgmt; |
@@ -1864,6 +2028,11 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info, | |||
1864 | 2028 | ||
1865 | lbs_deb_enter(LBS_DEB_WEXT); | 2029 | lbs_deb_enter(LBS_DEB_WEXT); |
1866 | 2030 | ||
2031 | if (!lbs_is_cmd_allowed(priv)) { | ||
2032 | ret = -EBUSY; | ||
2033 | goto out; | ||
2034 | } | ||
2035 | |||
1867 | if (vwrq->disabled) { | 2036 | if (vwrq->disabled) { |
1868 | lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0); | 2037 | lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0); |
1869 | goto out; | 2038 | goto out; |
@@ -1983,6 +2152,12 @@ static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info, | |||
1983 | 2152 | ||
1984 | lbs_deb_enter(LBS_DEB_WEXT); | 2153 | lbs_deb_enter(LBS_DEB_WEXT); |
1985 | 2154 | ||
2155 | if (!lbs_is_cmd_allowed(priv)) { | ||
2156 | ret = -EBUSY; | ||
2157 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
2158 | return ret; | ||
2159 | } | ||
2160 | |||
1986 | if (!priv->radio_on) { | 2161 | if (!priv->radio_on) { |
1987 | ret = -EINVAL; | 2162 | ret = -EINVAL; |
1988 | goto out; | 2163 | goto out; |
@@ -2110,6 +2285,12 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info, | |||
2110 | 2285 | ||
2111 | lbs_deb_enter(LBS_DEB_WEXT); | 2286 | lbs_deb_enter(LBS_DEB_WEXT); |
2112 | 2287 | ||
2288 | if (!lbs_is_cmd_allowed(priv)) { | ||
2289 | ret = -EBUSY; | ||
2290 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | ||
2291 | return ret; | ||
2292 | } | ||
2293 | |||
2113 | if (!priv->radio_on) | 2294 | if (!priv->radio_on) |
2114 | return -EINVAL; | 2295 | return -EINVAL; |
2115 | 2296 | ||