diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 610bfcee3cf6..ff6378276ff0 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1666,28 +1666,20 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, if (dev == priv->mesh_dev) return -EOPNOTSUPP; - lbs_deb_enter(LBS_DEB_CFG80211); - switch (type) { case NL80211_IFTYPE_MONITOR: - ret = lbs_set_monitor_mode(priv, 1); - break; case NL80211_IFTYPE_STATION: - if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) - ret = lbs_set_monitor_mode(priv, 0); - if (!ret) - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1); - break; case NL80211_IFTYPE_ADHOC: - if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) - ret = lbs_set_monitor_mode(priv, 0); - if (!ret) - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2); break; default: - ret = -ENOTSUPP; + return -EOPNOTSUPP; } + lbs_deb_enter(LBS_DEB_CFG80211); + + if (priv->iface_running) + ret = lbs_set_iface_type(priv, type); + if (!ret) priv->wdev->iftype = type; diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 9304e6fc421f..bc951ab4b681 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -9,6 +9,7 @@ #include #include +#include /* Should be terminated by a NULL entry */ struct lbs_fw_table { @@ -45,6 +46,7 @@ void lbs_host_to_card_done(struct lbs_private *priv); int lbs_start_iface(struct lbs_private *priv); int lbs_stop_iface(struct lbs_private *priv); +int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type); int lbs_rtap_supported(struct lbs_private *priv); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 6a326233391f..f78afd7bb768 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -99,6 +99,32 @@ u8 lbs_data_rate_to_fw_index(u32 rate) return 0; } +int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type) +{ + int ret = 0; + + switch (type) { + case NL80211_IFTYPE_MONITOR: + ret = lbs_set_monitor_mode(priv, 1); + break; + case NL80211_IFTYPE_STATION: + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) + ret = lbs_set_monitor_mode(priv, 0); + if (!ret) + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1); + break; + case NL80211_IFTYPE_ADHOC: + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) + ret = lbs_set_monitor_mode(priv, 0); + if (!ret) + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2); + break; + default: + ret = -ENOTSUPP; + } + return ret; +} + int lbs_start_iface(struct lbs_private *priv) { struct cmd_ds_802_11_mac_address cmd; @@ -120,6 +146,12 @@ int lbs_start_iface(struct lbs_private *priv) goto err; } + ret = lbs_set_iface_type(priv, priv->wdev->iftype); + if (ret) { + lbs_deb_net("set iface type failed\n"); + goto err; + } + lbs_update_channel(priv); priv->iface_running = true;