static int ieee80211_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); int type; if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) return -EOPNOTSUPP; switch (*mode) { case IW_MODE_INFRA: type = IEEE80211_IF_TYPE_STA; break; case IW_MODE_ADHOC: type = IEEE80211_IF_TYPE_IBSS; break; case IW_MODE_MONITOR: type = IEEE80211_IF_TYPE_MNTR; break; default: return -EINVAL; } if (type == sdata->vif.type) return 0; if (netif_running(dev)) return -EBUSY; ieee80211_if_reinit(dev); ieee80211_if_set_type(dev, type); return 0; }
static ssize_t store_add_iface(struct class_device *dev, const char *buf, size_t len) { struct ieee80211_local *local = to_ieee80211_local(dev); struct net_device *new_dev; int res; if (!capable(CAP_NET_ADMIN)) return -EPERM; if (len > IFNAMSIZ) return -EINVAL; res = rtnl_lock_local(local); if (res) return res; res = ieee80211_if_add(local->mdev, buf, 0, &new_dev); if (res == 0) ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA); rtnl_unlock(); return res < 0 ? res : len; }