aboutsummaryrefslogtreecommitdiff
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.c185
1 files changed, 183 insertions, 2 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index be837a0d251..38a451edb70 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)
priv->pending_assoc_req = NULL;
}
+/**
+ * @brief This function checks if the command is allowed.
+ *
+ * @param priv A pointer to lbs_private structure
+ * @return allowed or not allowed.
+ */
+
+int lbs_is_cmd_allowed(struct lbs_private *priv)
+{
+ int ret = 1;
+
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ if (!priv->is_auto_deep_sleep_enabled) {
+ if (priv->is_deep_sleep) {
+ lbs_deb_wext("IOCTLS called when station"
+ "is in deep sleep\n");
+ ret = 0;
+ }
+ }
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return ret;
+}
+
/**
* @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,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return -EBUSY;
+ }
+
cfp = lbs_find_cfp_by_band_and_channel(priv, 0,
priv->curbssparams.channel);
@@ -278,6 +308,12 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
if (vwrq->disabled)
val = MRVDRV_RTS_MAX_VALUE;
@@ -299,6 +335,11 @@ static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val);
if (ret)
goto out;
@@ -321,6 +362,12 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
if (vwrq->disabled)
val = MRVDRV_FRAG_MAX_VALUE;
@@ -342,6 +389,11 @@ static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val);
if (ret)
goto out;
@@ -391,6 +443,11 @@ static int lbs_get_txpow(struct net_device *dev,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
if (!priv->radio_on) {
lbs_deb_wext("tx power off\n");
vwrq->value = 0;
@@ -424,6 +481,11 @@ static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
return -EOPNOTSUPP;
@@ -472,6 +534,11 @@ static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
vwrq->disabled = 0;
if (vwrq->flags & IW_RETRY_LONG) {
@@ -709,6 +776,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
struct lbs_private *priv = dev->ml_priv;
+ int ret = 0;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -737,8 +805,54 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
"setting power timeout is not supported\n");
return -EINVAL;
} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
- lbs_deb_wext("setting power period not supported\n");
- return -EINVAL;
+ vwrq->value = vwrq->value / 1000;
+ if (!priv->enter_deep_sleep) {
+ lbs_pr_err("deep sleep feature is not implemented "
+ "for this interface driver\n");
+ return -EINVAL;
+ }
+
+ if (priv->connect_status == LBS_CONNECTED) {
+ if ((priv->is_auto_deep_sleep_enabled) &&
+ (vwrq->value == -1000)) {
+ lbs_exit_auto_deep_sleep(priv);
+ return 0;
+ } else {
+ lbs_pr_err("can't use deep sleep cmd in "
+ "connected state\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((vwrq->value < 0) && (vwrq->value != -1000)) {
+ lbs_pr_err("unknown option\n");
+ return -EINVAL;
+ }
+
+ if (vwrq->value > 0) {
+ if (!priv->is_auto_deep_sleep_enabled) {
+ priv->is_activity_detected = 0;
+ priv->auto_deep_sleep_timeout = vwrq->value;
+ lbs_enter_auto_deep_sleep(priv);
+ } else {
+ priv->auto_deep_sleep_timeout = vwrq->value;
+ lbs_deb_debugfs("auto deep sleep: "
+ "already enabled\n");
+ }
+ return 0;
+ } else {
+ if (priv->is_auto_deep_sleep_enabled) {
+ lbs_exit_auto_deep_sleep(priv);
+ /* Try to exit deep sleep if auto */
+ /*deep sleep disabled */
+ ret = lbs_set_deep_sleep(priv, 0);
+ }
+ if (vwrq->value == 0)
+ ret = lbs_set_deep_sleep(priv, 1);
+ else if (vwrq->value == -1000)
+ ret = lbs_set_deep_sleep(priv, 0);
+ return ret;
+ }
}
if (priv->psmode != LBS802_11POWERMODECAM) {
@@ -752,6 +866,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
}
lbs_deb_leave(LBS_DEB_WEXT);
+
return 0;
}
@@ -792,6 +907,9 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv))
+ return NULL;
+
priv->wstats.status = priv->mode;
/* 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,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
mutex_lock(&priv->lock);
assoc_req = lbs_get_association_request(priv);
if (!assoc_req) {
@@ -1000,6 +1124,12 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
u8 rates[MAX_RATES + 1];
lbs_deb_enter(LBS_DEB_WEXT);
+
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
lbs_deb_wext("vwrq->value %d\n", vwrq->value);
lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed);
@@ -1058,6 +1188,11 @@ static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return -EBUSY;
+ }
+
if (priv->connect_status == LBS_CONNECTED) {
vwrq->value = priv->cur_rate * 500000;
@@ -1084,6 +1219,11 @@ static int lbs_set_mode(struct net_device *dev,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
if ( (*uwrq != IW_MODE_ADHOC)
&& (*uwrq != IW_MODE_INFRA)
&& (*uwrq != IW_MODE_AUTO)) {
@@ -1325,6 +1465,12 @@ static int lbs_set_encode(struct net_device *dev,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
mutex_lock(&priv->lock);
assoc_req = lbs_get_association_request(priv);
if (!assoc_req) {
@@ -1508,6 +1654,12 @@ static int lbs_set_encodeext(struct net_device *dev,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
mutex_lock(&priv->lock);
assoc_req = lbs_get_association_request(priv);
if (!assoc_req) {
@@ -1720,6 +1872,12 @@ static int lbs_set_auth(struct net_device *dev,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
mutex_lock(&priv->lock);
assoc_req = lbs_get_association_request(priv);
if (!assoc_req) {
@@ -1822,6 +1980,12 @@ static int lbs_get_auth(struct net_device *dev,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
switch (dwrq->flags & IW_AUTH_INDEX) {
case IW_AUTH_KEY_MGMT:
dwrq->value = priv->secinfo.key_mgmt;
@@ -1864,6 +2028,11 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
if (vwrq->disabled) {
lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0);
goto out;
@@ -1983,6 +2152,12 @@ static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
if (!priv->radio_on) {
ret = -EINVAL;
goto out;
@@ -2110,6 +2285,12 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
+ if (!lbs_is_cmd_allowed(priv)) {
+ ret = -EBUSY;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
+ }
+
if (!priv->radio_on)
return -EINVAL;